explorer_show_frame(SW_SHOWNORMAL);
break;
+ case WM_DISPLAYCHANGE:
+ MoveWindow(_hwnd, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE);
+ MoveWindow(g_Globals._hwndShellView, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE);
+ MoveWindow(_desktopBar, 0, HIWORD(lparam) - DESKTOPBARBAR_HEIGHT, LOWORD(lparam), DESKTOPBARBAR_HEIGHT, TRUE);
+ break;
+
case WM_GETISHELLBROWSER:
return (LRESULT)static_cast<IShellBrowser*>(this);
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Group",0x00000000,"Video Init"
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ImagePath",0x00020000,"system32\drivers\blue.sys"
-HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000004
+HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Type",0x00010001,0x00000001
; Cdfs (ISO96660) filesystem driver
media\fonts\tahoma.ttf 3
media\fonts\tahomabd.ttf 3
+media\vgafonts\vgafonts.cab 4
+
media\nls\c_037.nls 1
media\nls\c_424.nls 1
media\nls\c_500.nls 1
typedef BOOL (WINAPI *SEEKPRINTER) (HANDLE,LARGE_INTEGER,PLARGE_INTEGER,DWORD,BOOL);
typedef BOOL (WINAPI *SPLREADPRINTER) (HANDLE,LPBYTE *,DWORD);
// Same as ddk/winsplp.h DriverUnloadComplete?
-typedef BOOL (WINAPI *SPLDRIVERUNLOADCOMPLETE) (LPWSTR);
+typedef BOOL (WINAPI *SPLDRIVERUNLOADCOMPLETE) (LPWSTR);
// Driver support:
// DrvDocumentEvent api/winddiui.h not W2k8 DocumentEventAW
typedef INT (WINAPI *DOCUMENTEVENT) (HANDLE,HDC,INT,ULONG,PVOID,ULONG,PVOID);
VOID
HEAP_free(LPVOID memory);
-VOID
+VOID
FASTCALL
FONT_TextMetricWToA(
- const TEXTMETRICW *ptmW,
+ const TEXTMETRICW *ptmW,
LPTEXTMETRICA ptmA
);
GdiSetLastError( DWORD dwErrCode );
DWORD WINAPI GdiGetCodePage(HDC);
-UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO );
+UINT FASTCALL DIB_BitmapBitsSize( CONST BITMAPINFO* );
int
WINAPI
INT iPixelFormat,
CONST PIXELFORMATDESCRIPTOR * ppfd)
{
+ /* Can only be set once */
+ INT current = GetPixelFormat(hdc);
+ if(current) return current == iPixelFormat ;
+
if (glSetPixelFormat == NULL)
if (OpenGLEnable() == FALSE)
return(0);
UINT
FASTCALL
-DIB_BitmapBitsSize( PBITMAPINFO Info )
+DIB_BitmapBitsSize( CONST BITMAPINFO* Info )
{
UINT Ret;
if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
- Ret = Core->bcHeight *
+ Ret = Core->bcHeight *
((Core->bcWidth * Core->bcPlanes * Core->bcBitCount + 31) & ~31 ) / 8;
}
else /* assume BITMAPINFOHEADER */
{
- if ((Info->bmiHeader.biCompression) &&
+ if ((Info->bmiHeader.biCompression) &&
(Info->bmiHeader.biCompression != BI_BITFIELDS))
return Info->bmiHeader.biSizeImage;
// Make Height positive always....
- Ret = abs(Info->bmiHeader.biHeight) *
+ Ret = abs(Info->bmiHeader.biHeight) *
((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes * Info->bmiHeader.biBitCount + 31) & ~31 ) / 8;
}
return Ret;
GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
{
int retSize;
-
+
if (lpbmi->bmiHeader.biSize == FIELD_OFFSET(BITMAPINFOHEADER, biPlanes))
{
/* Calc the bits Size and align it*/
- retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) *
- LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31)
+ retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) *
+ LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31)
& -32) / 8;
}
else
if (lpbmi->bmiHeader.biHeight >=0 )
{
/* Calc the bits Size and align it*/
- retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth *
+ retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth *
lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
}
else
{
/* Make height postiive if it negitve then calc the bits Size and align it*/
- retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth *
+ retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth *
lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
}
}
{ // Verify header due to converted may == info.
if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
{
- if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )
{
SetLastError(ERROR_INVALID_PARAMETER);
(!(pbm->bmWidthBytes & 1)) )
{
-
+
bitmap = CreateBitmap(pbm->bmWidth,
pbm->bmHeight,
pbm->bmPlanes,
{
if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
{
- if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
+ if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
lpbmi->bmiHeader.biCompression == BI_PNG )
{
SetLastError(ERROR_INVALID_PARAMETER);
LONG width, height, compr, dibsize;
WORD planes, bpp;
// PDC_ATTR pDc_Attr;
- PBITMAPINFO pConvertedInfo;
- UINT ConvertedInfoSize;
- UINT cjBmpScanSize;
- PVOID pvSafeBits = NULL;
+ UINT InfoSize = 0;
+ UINT cjBmpScanSize = 0;
HBITMAP hBmp;
+ NTSTATUS Status = STATUS_SUCCESS;
if (!Header) return 0;
- pConvertedInfo = ConvertBitmapInfo(Data, ColorUse,
- &ConvertedInfoSize, FALSE);
-
if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1)
{
GdiSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
- if ( pConvertedInfo )
- {
- if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
- {
- if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
- pConvertedInfo->bmiHeader.biCompression == BI_PNG )
- {
- hBmp = NULL;
- goto Exit;
- }
- }
- }
-
// For Icm support.
// GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
- cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
- DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", pConvertedInfo,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize);
+ if(Data)
+ {
+ _SEH2_TRY
+ {
+ cjBmpScanSize = DIB_BitmapBitsSize(Data);
+ CalculateColorTableSize(&Data->bmiHeader, &ColorUse, &InfoSize);
+ InfoSize += Data->bmiHeader.biSize;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+ }
+
+ if(!NT_SUCCESS(Status))
+ {
+ GdiSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", Data,bpp,dibsize,InfoSize,cjBmpScanSize);
if ( !width || !height )
hBmp = GetStockObject(DEFAULT_BITMAP);
else
{
- if ( Bits && Init == CBM_INIT )
- {
- pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
- if (pvSafeBits == NULL)
- {
- hBmp = NULL;
- goto Exit;
- }
- else
- {
- RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
- }
- }
-
hBmp = NtGdiCreateDIBitmapInternal(hDC,
width,
height,
Init,
- (LPBYTE)pvSafeBits,
- (PBITMAPINFO)pConvertedInfo,
+ (LPBYTE)Bits,
+ (LPBITMAPINFO)Data,
ColorUse,
- ConvertedInfoSize,
+ InfoSize,
cjBmpScanSize,
0,
0);
-
- if ( Bits && Init == CBM_INIT )
- RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
}
-Exit:
- if (Data != pConvertedInfo)
- RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
return hBmp;
}
if ( hOldBitmap )
{
- if ( hDC )
+ if ( hDC )
hPal = SelectPalette(SavehDC, (HPALETTE)GetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE), FALSE);
if ( lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
/*
if ( !pDc_Attr ||
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
- (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
{
LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc,
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
if (lpbmi != pConvertedInfo)
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
-
+
return LinesCopied;
}
}
}
#endif
- if ( iUsage ) // Save time, we only look at non RGB.
- {
- pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage,
- &ConvertedInfoSize, FALSE);
- if (!pConvertedInfo)
- {
+ pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage,
+ &ConvertedInfoSize, FALSE);
+ if (!pConvertedInfo)
+ {
return 0;
- }
- }
- else
- pConvertedInfo = (PBITMAPINFO)lpBitsInfo;
+ }
cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
/*
if ( !pDc_Attr ||
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
- (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
{
LinesCopied = NtGdiStretchDIBitsInternal( hdc,
{
UNICODE_STRING Device, Output;
HDC hDC = NULL;
- BOOL Display = FALSE, Default = TRUE;
+ BOOL Display = FALSE, Default = FALSE;
ULONG UMdhpdev = 0;
HANDLE hspool = NULL;
if ((!lpwszDevice) && (!lpwszDriver))
{
- Default = FALSE; // Ask Win32k to set Default device.
+ Default = TRUE; // Ask Win32k to set Default device.
Display = TRUE; // Most likely to be DISPLAY.
}
else
DPRINT1("Not a DISPLAY device! %wZ\n", &Device);
}
- hDC = NtGdiOpenDCW( (Default ? &Device : NULL),
+ hDC = NtGdiOpenDCW( (Default ? NULL : &Device),
(PDEVMODEW) lpInitData,
(lpwszOutput ? &Output : NULL),
iType, // DCW 0 and ICW 1.
DeleteObject(HGDIOBJ hObject)
{
UINT Type = 0;
-
+
/* From Wine: DeleteObject does not SetLastError() on a null object */
if(!hObject) return FALSE;
Type = GDI_HANDLE_GET_TYPE(hObject);
- if ((Type == GDI_OBJECT_TYPE_METAFILE) ||
+ if ((Type == GDI_OBJECT_TYPE_METAFILE) ||
(Type == GDI_OBJECT_TYPE_ENHMETAFILE))
return FALSE;
case GDI_OBJECT_TYPE_METADC:
return MFDRV_DeleteObject( hObject );
case GDI_OBJECT_TYPE_EMF:
- {
+ {
PLDC pLDC = GdiGetLDC(hObject);
if ( !pLDC ) return FALSE;
return EMFDRV_DeleteObject( hObject );
return NtGdiGetDeviceCaps(hDC,i);
}
DPRINT("Device CAPS2\n");
-
+
switch (i)
{
case DRIVERVERSION:
#if 0
case GDI_OBJECT_TYPE_METADC:
- return MFDRV_SelectObject( hDC, hGdiObj);
+ return MFDRV_SelectObject( hDC, hGdiObj);
case GDI_OBJECT_TYPE_EMF:
PLDC pLDC = GdiGetLDC(hDC);
if ( !pLDC ) return NULL;
HCURSOR
-CursorIconToCursor(HICON hIcon, BOOL SemiTransparent);
+CursorIconToCursor(HICON hIcon,
+ BOOL SemiTransparent);
+
+HICON CreateCursorIconFromData(PVOID ImageData,
+ ICONIMAGE* IconImage,
+ int cxDesired,
+ int cyDesired,
+ int xHotspot,
+ int yHotspot,
+ BOOL fIcon);
+
LONG rc;
UNICODE_STRING DeviceName;
PUNICODE_STRING pDeviceName = &DeviceName;
- LPDEVMODEW pDevModeW;
if (lpszDeviceName != NULL)
{
pDeviceName = NULL;
if (lpDevMode != NULL)
+ {
+ LPDEVMODEW pDevModeW;
pDevModeW = GdiConvertToDevmodeW(lpDevMode);
+ if(pDevModeW)
+ {
+ rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam );
+ RtlFreeHeap(GetProcessHeap(), 0, pDevModeW);
+ }
+ else
+ rc = DISP_CHANGE_SUCCESSFUL;
+ }
else
- pDevModeW = NULL;
-
- rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam );
-
- if (pDevModeW != NULL)
- RtlFreeHeap(GetProcessHeap(), 0, pDevModeW);
+ rc = NtUserChangeDisplaySettings ( pDeviceName, NULL, hwnd, dwflags, lParam );
if (lpszDeviceName != NULL)
RtlFreeUnicodeString ( &DeviceName );
DWORD dwflags)
{
if(lpDevMode)
- lpDevMode->dmDriverExtra = 0;
+ lpDevMode->dmDriverExtra = 0;
return ChangeDisplaySettingsExW ( NULL, lpDevMode, NULL, dwflags, 0 );
}
}
return Ret;
}
- // Wine Class tests:
+ // Wine Class tests:
/* Edit controls are special - they return a wndproc handle when
GetWindowLongPtr is called with a different A/W.
On the other hand there is no W->A->W conversion so this control
int SmallIconWidth;
int SmallIconHeight;
BITMAP StdBitmapInfo;
- HDC hInfoDc = NULL;
HDC hSourceDc = NULL;
HDC hDestDc = NULL;
ICONINFO SmallInfo;
return StdIcon;
}
- /* Get a handle to a info DC and handles to DCs which can be used to
- select a bitmap into. This is done to avoid triggering a switch to
- graphics mode (if we're currently in text/blue screen mode) */
- hInfoDc = CreateICW(NULL, NULL, NULL, NULL);
- if (NULL == hInfoDc)
- {
- ERR("Failed to create info DC\n");
- goto cleanup;
- }
hSourceDc = CreateCompatibleDC(NULL);
if (NULL == hSourceDc)
{
ERR("Failed to select source color bitmap\n");
goto cleanup;
}
- SmallInfo.hbmColor = CreateCompatibleBitmap(hInfoDc, SmallIconWidth,
+ SmallInfo.hbmColor = CreateCompatibleBitmap(hSourceDc, SmallIconWidth,
SmallIconHeight);
if (NULL == SmallInfo.hbmColor)
{
ERR("Failed to select source mask bitmap\n");
goto cleanup;
}
- SmallInfo.hbmMask = CreateBitmap(SmallIconWidth, SmallIconHeight, 1, 1,
- NULL);
+ SmallInfo.hbmMask = CreateCompatibleBitmap(hSourceDc, SmallIconWidth, SmallIconHeight);
if (NULL == SmallInfo.hbmMask)
{
ERR("Failed to create mask bitmap\n");
{
DeleteDC(hSourceDc);
}
- if (NULL != hInfoDc)
- {
- DeleteDC(hInfoDc);
- }
return SmallIcon;
}
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
clsMenuName.pusMenuName = &MenuName;
-
+
Atom = NtUserRegisterClassExWOW( &WndClass,
- &ClassName,
+ &ClassName,
NULL, //PUNICODE_STRING ClsNVersion,
&clsMenuName,
fnID,
void *color_bits, *mask_bits;
BOOL ret = FALSE;
HDC hdc = 0;
+ static HDC hScreenDC = 0;
if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] )))))
return FALSE;
- if (!(hdc = CreateCompatibleDC( 0 ))) goto done;
+ if(!hScreenDC)
+ {
+ hScreenDC = GetDC(0);
+ if(!hScreenDC) goto done;
+ }
+ if (!(hdc = CreateCompatibleDC(hScreenDC))) goto done;
memcpy( info, bmi, size );
info->bmiHeader.biHeight /= 2;
else
{
if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done;
- if (!(*color = CreateBitmap( width, height, bmi->bmiHeader.biPlanes,
- bmi->bmiHeader.biBitCount, NULL )))
+ if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hScreenDC, PLANES),
+ GetDeviceCaps(hScreenDC, BITSPIXEL), NULL )))
{
DeleteObject( *mask );
goto done;
ret = TRUE;
done:
- DeleteDC( hdc );
+ if(hdc) DeleteDC( hdc );
HeapFree( GetProcessHeap(), 0, info );
return ret;
}
}
if (flags & DSS_DISABLED)
- hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
+ hbrtmp = GetSysColorBrush(COLOR_3DHILIGHT);
else if (flags & DSS_DEFAULT)
- hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
+ hbrtmp = GetSysColorBrush(COLOR_3DSHADOW);
/* Draw light or dark shadow */
if (flags & (DSS_DISABLED|DSS_DEFAULT))
if(!BitBlt(hdc, x+1, y+1, cx, cy, memdc, 0, 0, 0x00B8074A))
goto cleanup;
SelectObject(hdc, hbsave);
- DeleteObject(hbrtmp);
- hbrtmp = 0;
}
if (flags & DSS_DISABLED)
{
- hbr = hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
+ hbr = hbrtmp = GetSysColorBrush(COLOR_3DSHADOW);
if(!hbrtmp)
goto cleanup;
}
SelectObject(hdc, hbsave);
if(hbmsave)
SelectObject(memdc, hbmsave);
- if(hbrtmp)
- DeleteObject(hbrtmp);
if(hbm)
DeleteObject(hbm);
if(memdc)
case WM_CLOSE:
return 0;
+ case WM_DISPLAYCHANGE:
+ MoveWindow(Wnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
+ break;
+
case WM_NOTIFY:
{
PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam;
<include base="console">.</include>
<compilerflag compilerset="gcc">-fms-extensions</compilerflag>
<library>ntdll</library>
- <library>user32</library>
- <library>gdi32</library>
- <library>advapi32</library>
+ <library delayimport="true">user32</library>
+ <library delayimport="true">gdi32</library>
+ <library delayimport="true">advapi32</library>
+ <library>delayimp</library>
<library>win32ksys</library>
<library>psapi</library>
<library>pseh</library>
--- /dev/null
+/*
+ * PROJECT: Win32 subsystem
+ * LICENSE: See COPYING in the top level directory
+ * FILE: subsystems/win32/win32k/dib/stretchblt.c
+ * PURPOSE: AlphaBlend implementation suitable for all bit depths
+ * PROGRAMMERS: Jérôme Gardou
+ */
+
+#include <win32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+typedef union
+{
+ ULONG ul;
+ struct
+ {
+ UCHAR red;
+ UCHAR green;
+ UCHAR blue;
+ UCHAR alpha;
+ } col;
+} NICEPIXEL32;
+
+static __inline UCHAR
+Clamp8(ULONG val)
+{
+ return (val > 255) ? 255 : val;
+}
+
+BOOLEAN
+DIB_XXBPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
+ RECTL* SourceRect, CLIPOBJ* ClipRegion,
+ XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
+{
+ INT DstX, DstY, SrcX, SrcY;
+ BLENDFUNCTION BlendFunc;
+ register NICEPIXEL32 DstPixel32;
+ register NICEPIXEL32 SrcPixel32;
+ UCHAR Alpha, SrcBpp = BitsPerFormat(Source->iBitmapFormat);
+ EXLATEOBJ* pexlo;
+ EXLATEOBJ exloSrcRGB, exloDstRGB, exloRGBSrc;
+ PFN_DIB_PutPixel pfnDibPutPixel = DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel;
+
+ DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
+ SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
+ DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
+
+ BlendFunc = BlendObj->BlendFunction;
+ if (BlendFunc.BlendOp != AC_SRC_OVER)
+ {
+ DPRINT1("BlendOp != AC_SRC_OVER\n");
+ return FALSE;
+ }
+ if (BlendFunc.BlendFlags != 0)
+ {
+ DPRINT1("BlendFlags != 0\n");
+ return FALSE;
+ }
+ if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
+ {
+ DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
+ return FALSE;
+ }
+ if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
+ SrcBpp != 32)
+ {
+ DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
+ return FALSE;
+ }
+
+ if (!ColorTranslation)
+ {
+ DPRINT1("ColorTranslation must not be NULL!\n");
+ return FALSE;
+ }
+
+ pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
+ EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloDstRGB, pexlo->ppalDst, &gpalRGB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloRGBSrc, &gpalRGB, pexlo->ppalSrc, 0, 0, 0);
+
+ SrcY = SourceRect->top;
+ DstY = DestRect->top;
+ while ( DstY < DestRect->bottom )
+ {
+ SrcX = SourceRect->left;
+ DstX = DestRect->left;
+ while(DstX < DestRect->right)
+ {
+ SrcPixel32.ul = DIB_GetSource(Source, SrcX, SrcY, &exloSrcRGB.xlo);
+ SrcPixel32.col.red = (SrcPixel32.col.red * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel32.col.green = (SrcPixel32.col.green * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel32.col.blue = (SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha) / 255;
+
+ Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
+ (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha) / 255 :
+ BlendFunc.SourceConstantAlpha ;
+
+ DstPixel32.ul = DIB_GetSource(Dest, DstX, DstY, &exloDstRGB.xlo);
+ DstPixel32.col.red = Clamp8((DstPixel32.col.red * (255 - Alpha)) / 255 + SrcPixel32.col.red) ;
+ DstPixel32.col.green = Clamp8((DstPixel32.col.green * (255 - Alpha)) / 255 + SrcPixel32.col.green) ;
+ DstPixel32.col.blue = Clamp8((DstPixel32.col.blue * (255 - Alpha)) / 255 + SrcPixel32.col.blue) ;
+ DstPixel32.ul = XLATEOBJ_iXlate(&exloRGBSrc.xlo, DstPixel32.ul);
+ pfnDibPutPixel(Dest, DstX, DstY, XLATEOBJ_iXlate(ColorTranslation, DstPixel32.ul));
+
+ DstX++;
+ SrcX = SourceRect->left + ((DstX-DestRect->left)*(SourceRect->right - SourceRect->left))
+ /(DestRect->right-DestRect->left);
+ }
+ DstY++;
+ SrcY = SourceRect->top + ((DstY-DestRect->top)*(SourceRect->bottom - SourceRect->top))
+ /(DestRect->bottom-DestRect->top);
+ }
+
+ EXLATEOBJ_vCleanup(&exloDstRGB);
+ EXLATEOBJ_vCleanup(&exloRGBSrc);
+ EXLATEOBJ_vCleanup(&exloSrcRGB);
+
+ return TRUE;
+}
+
{
DIB_1BPP_PutPixel, DIB_1BPP_GetPixel, DIB_1BPP_HLine, DIB_1BPP_VLine,
DIB_1BPP_BitBlt, DIB_1BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_1BPP_AlphaBlend
+ DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_4BPP */
{
DIB_4BPP_PutPixel, DIB_4BPP_GetPixel, DIB_4BPP_HLine, DIB_4BPP_VLine,
DIB_4BPP_BitBlt, DIB_4BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_4BPP_AlphaBlend
+ DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_8BPP */
{
DIB_8BPP_PutPixel, DIB_8BPP_GetPixel, DIB_8BPP_HLine, DIB_8BPP_VLine,
DIB_8BPP_BitBlt, DIB_8BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_8BPP_AlphaBlend
+ DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_16BPP */
{
DIB_16BPP_PutPixel, DIB_16BPP_GetPixel, DIB_16BPP_HLine, DIB_16BPP_VLine,
DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
- DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_16BPP_AlphaBlend
+ DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_XXBPP_AlphaBlend
},
/* BMF_24BPP */
{
BOOLEAN DIB_1BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_1BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_1BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_4BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_4BPP_GetPixel(SURFOBJ*,LONG,LONG);
BOOLEAN DIB_4BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_4BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_4BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_8BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_8BPP_GetPixel(SURFOBJ*,LONG,LONG);
BOOLEAN DIB_8BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_8BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_8BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_16BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_16BPP_GetPixel(SURFOBJ*,LONG,LONG);
BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
-BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
VOID DIB_24BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG);
ULONG DIB_24BPP_GetPixel(SURFOBJ*,LONG,LONG);
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,ROP4);
BOOLEAN DIB_XXBPP_FloodFillSolid(SURFOBJ*, BRUSHOBJ*, RECTL*, POINTL*, ULONG, UINT);
+BOOLEAN DIB_XXBPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
extern unsigned char notmask[2];
extern unsigned char altnotmask[2];
return TRUE;
}
-typedef union
-{
- ULONG ul;
- struct
- {
- UCHAR red;
- UCHAR green;
- UCHAR blue;
- UCHAR alpha;
- } col;
-} NICEPIXEL32;
-
-typedef union
-{
- USHORT us;
- struct
- {
- USHORT red:5,
- green:6,
- blue:5;
- } col;
-} NICEPIXEL16;
-
-static __inline UCHAR
-Clamp5(ULONG val)
-{
- return (val > 31) ? 31 : val;
-}
-
-static __inline UCHAR
-Clamp8(ULONG val)
-{
- return (val > 255) ? 255 : val;
-}
-
-static __inline UCHAR
-Clamp6(ULONG val)
-{
- return (val > 63) ? 63 : val;
-}
-
-BOOLEAN
-DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- INT Rows, Cols, SrcX, SrcY;
- register PUSHORT Dst;
- ULONG DstDelta;
- BLENDFUNCTION BlendFunc;
- register NICEPIXEL16 SrcPixel16;
- register NICEPIXEL16 DstPixel16;
- register NICEPIXEL32 SrcPixel32;
- register NICEPIXEL32 DstPixel32;
- UCHAR Alpha, SrcBpp;
- EXLATEOBJ *pexlo;
- EXLATEOBJ exloDst2Src;
-
- DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
- SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
- DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
-
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
- BlendFunc = BlendObj->BlendFunction;
- if (BlendFunc.BlendOp != AC_SRC_OVER)
- {
- DPRINT1("BlendOp != AC_SRC_OVER\n");
- return FALSE;
- }
- if (BlendFunc.BlendFlags != 0)
- {
- DPRINT1("BlendFlags != 0\n");
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
- {
- DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
- BitsPerFormat(Source->iBitmapFormat) != 32)
- {
- DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
- return FALSE;
- }
-
- if (!ColorTranslation)
- {
- DPRINT1("ColorTranslation must not be NULL!\n");
- return FALSE;
- }
-
- pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
- EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0);
-
- Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
- (DestRect->left << 1));
- DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 1);
- SrcBpp = BitsPerFormat(Source->iBitmapFormat);
-
- Rows = DestRect->bottom - DestRect->top;
- SrcY = SourceRect->top;
- while (--Rows >= 0)
- {
- Cols = DestRect->right - DestRect->left;
- SrcX = SourceRect->left;
- while (--Cols >= 0)
- {
- if (SrcBpp <= 16)
- {
- SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel32.col.red = (SrcPixel16.col.red << 3);
- SrcPixel32.col.green = (SrcPixel16.col.green << 2);
- SrcPixel32.col.blue = (SrcPixel16.col.blue << 3);
-
- SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.alpha = (SrcBpp == 32) ?
- (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) :
- BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
-
- DstPixel16.us = *Dst;
- DstPixel16.col.red = Clamp5(DstPixel16.col.red * (255 - Alpha) / 255 +
- (SrcPixel32.col.red >> 3));
-
- DstPixel16.col.green = Clamp6(DstPixel16.col.green * (255 - Alpha) / 255 +
- (SrcPixel32.col.green >> 2));
-
- DstPixel16.col.blue = Clamp5(DstPixel16.col.blue * (255 - Alpha) / 255 +
- (SrcPixel32.col.blue >> 3));
-
- *Dst++ = DstPixel16.us;
- }
- else
- {
- SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
-
- SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.alpha = (SrcBpp == 32) ?
- (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) :
- BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
-
- DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst);
- SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red);
- SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
- SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue);
- *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul);
- }
- }
-
- Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
- }
-
- EXLATEOBJ_vCleanup(&exloDst2Src);
-
- return TRUE;
-}
-
/* EOF */
VOID
DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
{
- while(x1 < x2)
+ while(x1 < x2)
{
DIB_1BPP_PutPixel(SurfObj, x1, y, c);
x1++;
VOID
DIB_1BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
{
- while(y1 < y2)
+ while(y1 < y2)
{
DIB_1BPP_PutPixel(SurfObj, x, y1, c);
y1++;
return FALSE;
}
-BOOLEAN
-DIB_1BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
/* EOF */
LONG lDelta = SurfObj->lDelta;
c &= 0xFFFFFF;
- while(y1++ < y2)
+ while(y1++ < y2)
{
*(PUSHORT)(addr) = c & 0xFFFF;
*(addr + 2) = c >> 16;
{
INT Rows, Cols, SrcX, SrcY;
register PUCHAR Dst;
- ULONG DstDelta;
BLENDFUNCTION BlendFunc;
register NICEPIXEL32 DstPixel, SrcPixel;
UCHAR Alpha, SrcBpp;
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
BlendFunc = BlendObj->BlendFunction;
if (BlendFunc.BlendOp != AC_SRC_OVER)
{
Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
(DestRect->left * 3));
- DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) * 3);
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
- Rows = DestRect->bottom - DestRect->top;
+ Rows = 0;
SrcY = SourceRect->top;
- while (--Rows >= 0)
- {
- Cols = DestRect->right - DestRect->left;
- SrcX = SourceRect->left;
- while (--Cols >= 0)
+ while (++Rows <= DestRect->bottom - DestRect->top)
+ {
+ Cols = 0;
+ SrcX = SourceRect->left;
+ while (++Cols <= DestRect->right - DestRect->left)
+ {
+ SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation);
+ SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255;
+ if (!(BlendFunc.AlphaFormat & AC_SRC_ALPHA))
{
- SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
-
- /* copy only 24bits of dst */
- DstPixel.ul = *(PUSHORT)(Dst) + (*(Dst+2) << 16);
- DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
- DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
- DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
- /* copy back 24bits of result */
- *(PUSHORT)(Dst) = (USHORT)(DstPixel.ul & 0xFFFF);
- *(Dst + 2) = (UCHAR)((DstPixel.ul >> 16) & 0xFF);
- Dst = (PUCHAR)((ULONG_PTR)Dst + 3);
+ Alpha = BlendFunc.SourceConstantAlpha ;
}
- Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
- }
+ else
+ {
+ Alpha = (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255;
+ }
+
+ DstPixel.col.red = Clamp8((*Dst * (255 - Alpha)) / 255 + SrcPixel.col.red) ;
+ DstPixel.col.green = Clamp8((*(Dst+1) * (255 - Alpha) / 255 + SrcPixel.col.green)) ;
+ DstPixel.col.blue = Clamp8((*(Dst+2) * (255 - Alpha)) / 255 + SrcPixel.col.blue) ;
+ *Dst++ = DstPixel.col.red;
+ *Dst++ = DstPixel.col.green;
+ *Dst++ = DstPixel.col.blue;
+ SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left);
+ }
+ Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) +
+ (DestRect->left*3));
+ SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top);
+ }
return TRUE;
}
PBYTE SourceBits_4BPP, SourceLine_4BPP;
PDWORD Source32, Dest32;
- DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
- + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta)
+ DestBits = (PBYTE)BltInfo->DestSurface->pvScan0
+ + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta)
+ 4 * BltInfo->DestRect.left;
switch (BltInfo->SourceSurface->iBitmapFormat)
break;
case BMF_4BPP:
- SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0
- + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0
+ + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ (BltInfo->SourcePoint.x >> 1);
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
break;
case BMF_24BPP:
- SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0
- + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0
+ + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta)
+ 3 * BltInfo->SourcePoint.x;
DestLine = DestBits;
break;
case BMF_32BPP:
- if (NULL == BltInfo->XlateSourceToDest ||
+ if (NULL == BltInfo->XlateSourceToDest ||
0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
{
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
}
else
{
- SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
- + ((BltInfo->SourcePoint.y
- + BltInfo->DestRect.bottom
- - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta)
+ SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0
+ + ((BltInfo->SourcePoint.y
+ + BltInfo->DestRect.bottom
+ - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta)
+ 4 * BltInfo->SourcePoint.x;
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left;
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
{
INT Rows, Cols, SrcX, SrcY;
register PULONG Dst;
- ULONG DstDelta;
BLENDFUNCTION BlendFunc;
register NICEPIXEL32 DstPixel, SrcPixel;
UCHAR Alpha, SrcBpp;
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
BlendFunc = BlendObj->BlendFunction;
if (BlendFunc.BlendOp != AC_SRC_OVER)
{
Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
(DestRect->left << 2));
- DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 2);
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
- Rows = DestRect->bottom - DestRect->top;
- SrcY = SourceRect->top;
- while (--Rows >= 0)
+ Rows = 0;
+ SrcY = SourceRect->top;
+ while (++Rows <= DestRect->bottom - DestRect->top)
{
- Cols = DestRect->right - DestRect->left;
+ Cols = 0;
SrcX = SourceRect->left;
- while (--Cols >= 0)
+ while (++Cols <= DestRect->right - DestRect->left)
{
- SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
+ SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation);
+ SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255;
+ SrcPixel.col.alpha = (32 == SrcBpp) ?
+ (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255 :
+ BlendFunc.SourceConstantAlpha ;
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
+ SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha ;
DstPixel.ul = *Dst;
- DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
- DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
- DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
- DstPixel.col.alpha = Clamp8(DstPixel.col.alpha * (255 - Alpha) / 255 + SrcPixel.col.alpha);
+ DstPixel.col.red = Clamp8((DstPixel.col.red * (255 - Alpha)) / 255 + SrcPixel.col.red) ;
+ DstPixel.col.green = Clamp8((DstPixel.col.green * (255 - Alpha)) / 255 + SrcPixel.col.green) ;
+ DstPixel.col.blue = Clamp8((DstPixel.col.blue * (255 - Alpha)) / 255 + SrcPixel.col.blue) ;
+ DstPixel.col.alpha = Clamp8((DstPixel.col.alpha * (255 - Alpha)) / 255 + SrcPixel.col.alpha) ;
*Dst++ = DstPixel.ul;
+ SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left);
}
- Dst = (PULONG)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
+ Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) +
+ (DestRect->left << 2));
+ SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top);
}
return TRUE;
PBYTE addr = (PBYTE)SurfObj->pvScan0 + (x1>>1) + y * SurfObj->lDelta;
LONG cx = x1;
- while(cx < x2)
+ while(cx < x2)
{
*addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2));
if((++x1 & 1) == 0)
int lDelta = SurfObj->lDelta;
addr += (x>>1) + y1 * lDelta;
- while(y1++ < y2)
+ while(y1++ < y2)
{
*addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2));
addr += lDelta;
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
{
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
- }
- else
+ }
+ else
{
DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
}
return FALSE;
}
-BOOLEAN
-DIB_4BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
/* EOF */
LONG lDelta = SurfObj->lDelta;
byteaddr = addr;
- while(y1++ < y2)
+ while(y1++ < y2)
{
*addr = c;
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
{
DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
- }
- else
+ }
+ else
{
DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
}
return TRUE;
}
-typedef union {
- ULONG ul;
- struct {
- UCHAR red;
- UCHAR green;
- UCHAR blue;
- UCHAR alpha;
- } col;
-} NICEPIXEL32;
-
-typedef union {
- USHORT us;
- struct {
- USHORT red:5,
- green:6,
- blue:5;
- } col;
-} NICEPIXEL16;
-
-static __inline UCHAR
-Clamp8(ULONG val)
-{
- return (val > 255) ? 255 : val;
-}
-
-BOOLEAN
-DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
- RECTL* SourceRect, CLIPOBJ* ClipRegion,
- XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
-{
- INT Rows, Cols, SrcX, SrcY;
- register PUCHAR Dst;
- ULONG DstDelta;
- BLENDFUNCTION BlendFunc;
- register NICEPIXEL32 DstPixel32;
- register NICEPIXEL32 SrcPixel32;
- register NICEPIXEL16 SrcPixel16;
- UCHAR Alpha, SrcBpp;
- EXLATEOBJ exloDst2Src;
- EXLATEOBJ* pexlo;
-
- DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
- SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
- DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
-
- ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
- DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
-
- BlendFunc = BlendObj->BlendFunction;
- if (BlendFunc.BlendOp != AC_SRC_OVER)
- {
- DPRINT1("BlendOp != AC_SRC_OVER\n");
- return FALSE;
- }
- if (BlendFunc.BlendFlags != 0)
- {
- DPRINT1("BlendFlags != 0\n");
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
- {
- DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
- return FALSE;
- }
- if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
- BitsPerFormat(Source->iBitmapFormat) != 32)
- {
- DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
- return FALSE;
- }
- if (!ColorTranslation)
- {
- DPRINT1("ColorTranslation must not be NULL!\n");
- return FALSE;
- }
-
- pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
- EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0);
-
- Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
- DestRect->left);
- DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);
- SrcBpp = BitsPerFormat(Source->iBitmapFormat);
-
- Rows = DestRect->bottom - DestRect->top;
- SrcY = SourceRect->top;
- while (--Rows >= 0)
- {
- Cols = DestRect->right - DestRect->left;
- SrcX = SourceRect->left;
- while (--Cols >= 0)
- {
- if (SrcBpp <= 16)
- {
- SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel32.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
- SrcPixel32.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
- SrcPixel32.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
- }
- else
- {
- SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
- }
- SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
- SrcPixel32.col.alpha = (SrcBpp == 32) ? (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
-
- Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
- SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
-
- DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst);
- SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red);
- SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
- SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue);
- *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul);
- }
- Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
- SrcY++;
- }
-
- EXLATEOBJ_vCleanup(&exloDst2Src);
-
- return TRUE;
-}
-
/* EOF */
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI alpha blending functions
IN PRECTL SourceRect,
IN BLENDOBJ *BlendObj)
{
- RECTL SourceStretchedRect;
- SIZEL SourceStretchedSize;
- HBITMAP SourceStretchedBitmap = 0;
- SURFOBJ* SourceStretchedObj = NULL;
RECTL InputRect;
RECTL OutputRect;
RECTL ClipRect;
INTENG_ENTER_LEAVE EnterLeaveDest;
SURFOBJ* InputObj;
SURFOBJ* OutputObj;
- LONG Width;
LONG ClippingType;
RECT_ENUM RectEnum;
BOOL EnumMore;
InputRect = *SourceRect;
if ( (InputRect.top < 0) || (InputRect.bottom < 0) ||
(InputRect.left < 0) || (InputRect.right < 0) ||
- InputRect.right > psoSource->sizlBitmap.cx ||
+ InputRect.right > psoSource->sizlBitmap.cx ||
InputRect.bottom > psoSource->sizlBitmap.cy )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return TRUE;
}
- /* Stretch source if needed */
- if (OutputRect.right - OutputRect.left != InputRect.right - InputRect.left ||
- OutputRect.bottom - OutputRect.top != InputRect.bottom - InputRect.top)
- {
- SourceStretchedSize.cx = OutputRect.right - OutputRect.left;
- SourceStretchedSize.cy = OutputRect.bottom - OutputRect.top;
- Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx, BitsPerFormat(psoSource->iBitmapFormat));
- /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and IntEngStretchBlt
- if possible to get a HW accelerated stretch. */
- SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width, psoSource->iBitmapFormat,
- BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
- if (SourceStretchedBitmap == 0)
- {
- DPRINT1("EngCreateBitmap failed!\n");
- return FALSE;
- }
- SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap);
- if (SourceStretchedObj == NULL)
- {
- DPRINT1("EngLockSurface failed!\n");
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- return FALSE;
- }
-
- SourceStretchedRect.left = 0;
- SourceStretchedRect.right = SourceStretchedSize.cx;
- SourceStretchedRect.top = 0;
- SourceStretchedRect.bottom = SourceStretchedSize.cy;
- /* FIXME: IntEngStretchBlt isn't used here atm because it results in a
- try to acquire an already acquired mutex (lock the already locked source surface) */
- /*if (!IntEngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL,
- NULL, &SourceStretchedRect, SourceRect, NULL,
- NULL, NULL, COLORONCOLOR))*/
- if (!EngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL, NULL,
- NULL, NULL, &SourceStretchedRect, &InputRect,
- NULL, COLORONCOLOR))
- {
- DPRINT1("EngStretchBlt failed!\n");
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- return FALSE;
- }
- InputRect.top = SourceStretchedRect.top;
- InputRect.bottom = SourceStretchedRect.bottom;
- InputRect.left = SourceStretchedRect.left;
- InputRect.right = SourceStretchedRect.right;
- psoSource = SourceStretchedObj;
- }
-
/* Now call the DIB function */
if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj))
{
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
return FALSE;
}
InputRect.left += Translate.x;
if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj))
{
- IntEngLeave(&EnterLeaveSource);
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
return FALSE;
}
OutputRect.left += Translate.x;
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
- if (SourceStretchedObj != NULL)
- {
- EngFreeMem(SourceStretchedObj->pvBits);
- EngUnlockSurface(SourceStretchedObj);
- }
- if (SourceStretchedBitmap != 0)
- {
- EngDeleteSurface((HSURF)SourceStretchedBitmap);
- }
-
return Ret;
}
return TRUE;
}
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top,
- DestRect->right, DestRect->bottom);
-
- if (psoSource != psoDest)
- SURFACE_LockBitmapBits(psurfSource);
- MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top,
- SourceRect->right, SourceRect->bottom);
-
/* Call the driver's DrvAlphaBlend if available */
- if (psurfDest->flHooks & HOOK_ALPHABLEND)
+ if (psurfDest->flags & HOOK_ALPHABLEND)
{
ret = GDIDEVFUNCS(psoDest).AlphaBlend(
psoDest, psoSource, ClipRegion, ColorTranslation,
DestRect, SourceRect, BlendObj);
}
- MouseSafetyOnDrawEnd(psoSource);
- if (psoSource != psoDest)
- SURFACE_UnlockBitmapBits(psurfSource);
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
return ret;
}
}
BOOL APIENTRY
-IntEngBitBltEx(
+IntEngBitBlt(
SURFOBJ *psoTrg,
SURFOBJ *psoSrc,
SURFOBJ *psoMask,
POINTL *pptlMask,
BRUSHOBJ *pbo,
POINTL *pptlBrush,
- ROP4 rop4,
- BOOL bRemoveMouse)
+ ROP4 rop4)
{
SURFACE *psurfTrg;
SURFACE *psurfSrc = NULL;
psurfSrc = NULL;
}
- if (bRemoveMouse)
- {
- SURFACE_LockBitmapBits(psurfTrg);
-
- if (psoSrc)
- {
- if (psoSrc != psoTrg)
- {
- SURFACE_LockBitmapBits(psurfSrc);
- }
- MouseSafetyOnDrawStart(psoSrc, rclSrc.left, rclSrc.top,
- rclSrc.right, rclSrc.bottom);
- }
- MouseSafetyOnDrawStart(psoTrg, rclClipped.left, rclClipped.top,
- rclClipped.right, rclClipped.bottom);
- }
-
/* Is the target surface device managed? */
- if (psurfTrg->flHooks & HOOK_BITBLT)
+ if (psurfTrg->flags & HOOK_BITBLT)
{
/* Is the source a different device managed surface? */
- if (psoSrc && psoSrc->hdev != psoTrg->hdev && psurfSrc->flHooks & HOOK_BITBLT)
+ if (psoSrc && psoSrc->hdev != psoTrg->hdev && psurfSrc->flags & HOOK_BITBLT)
{
DPRINT1("Need to copy to standard bitmap format!\n");
ASSERT(FALSE);
}
/* Is the source surface device managed? */
- else if (psoSrc && psurfSrc->flHooks & HOOK_BITBLT)
+ else if (psoSrc && psurfSrc->flags & HOOK_BITBLT)
{
pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt;
}
// FIXME: cleanup temp surface!
- if (bRemoveMouse)
- {
- MouseSafetyOnDrawEnd(psoTrg);
- if (psoSrc)
- {
- MouseSafetyOnDrawEnd(psoSrc);
- if (psoSrc != psoTrg)
- {
- SURFACE_UnlockBitmapBits(psurfSrc);
- }
- }
-
- SURFACE_UnlockBitmapBits(psurfTrg);
- }
-
return bResult;
}
ASSERT(psoDest);
psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
-
/* Dummy BitBlt to let driver know that it should flush its changes.
This should really be done using a call to DrvSynchronizeSurface,
but the VMware driver doesn't hook that call. */
- IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
+ IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
- R4_NOOP, FALSE);
+ R4_NOOP);
ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation,
&OutputRect, &InputPoint, pbo, BrushOrigin);
/* Dummy BitBlt to let driver know that something has changed. */
- IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
+ IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation,
DestRect, pptlMask, pptlMask, pbo, BrushOrigin,
- R4_NOOP, FALSE);
-
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
+ R4_NOOP);
return ret;
}
ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL);
psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
- SURFACE_LockBitmapBits(psurfSource);
-
psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- if (psoDest != psoSource)
- {
- SURFACE_LockBitmapBits(psurfDest);
- }
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
// mark the copy block function to be DrvCopyBits instead of the
if (psoDest->iType!=STYPE_BITMAP)
{
/* FIXME: Eng* functions shouldn't call Drv* functions. ? */
- if (psurfDest->flHooks & HOOK_COPYBITS)
+ if (psurfDest->flags & HOOK_COPYBITS)
{
ret = GDIDEVFUNCS(psoDest).CopyBits(
psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
if (psoSource->iType!=STYPE_BITMAP)
{
/* FIXME: Eng* functions shouldn't call Drv* functions. ? */
- if (psurfSource->flHooks & HOOK_COPYBITS)
+ if (psurfSource->flags & HOOK_COPYBITS)
{
ret = GDIDEVFUNCS(psoSource).CopyBits(
psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
}
cleanup:
- if (psoDest != psoSource)
- {
- SURFACE_UnlockBitmapBits(psurfDest);
- }
- SURFACE_UnlockBitmapBits(psurfSource);
-
return ret;
}
RECTL *prclDest,
POINTL *ptlSource)
{
- BOOL bResult;
-
- MouseSafetyOnDrawStart(psoSource, ptlSource->x, ptlSource->y,
- (ptlSource->x + abs(prclDest->right - prclDest->left)),
- (ptlSource->y + abs(prclDest->bottom - prclDest->top)));
-
- MouseSafetyOnDrawStart(psoDest, prclDest->left, prclDest->top, prclDest->right, prclDest->bottom);
-
- bResult = EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
-
- MouseSafetyOnDrawEnd(psoDest);
- MouseSafetyOnDrawEnd(psoSource);
-
- return bResult;
+ return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
}
#define NDEBUG
#include <debug.h>
+PGRAPHICS_DEVICE gpPrimaryGraphicsDevice;
+PGRAPHICS_DEVICE gpVgaGraphicsDevice;
+
+static PGRAPHICS_DEVICE gpGraphicsDeviceFirst = NULL;
+static PGRAPHICS_DEVICE gpGraphicsDeviceLast = NULL;
+static HSEMAPHORE ghsemGraphicsDeviceList;
+static ULONG giDevNum = 1;
+
+BOOL
+NTAPI
+InitDeviceImpl()
+{
+ ghsemGraphicsDeviceList = EngCreateSemaphore();
+ if (!ghsemGraphicsDeviceList)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpRegisterGraphicsDevice(
+ PUNICODE_STRING pustrDeviceName,
+ PUNICODE_STRING pustrDiplayDrivers,
+ PUNICODE_STRING pustrDescription,
+ PDEVMODEW pdmDefault)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVICE_OBJECT pDeviceObject;
+ PFILE_OBJECT pFileObject;
+ NTSTATUS Status;
+ PWSTR pwsz;
+ ULONG i, cj, cModes = 0;
+ BOOL bEnable = TRUE;
+ PDEVMODEINFO pdminfo;
+ PDEVMODEW pdm, pdmEnd;
+ PLDEVOBJ pldev;
+
+ DPRINT1("EngpRegisterGraphicsDevice(%S)\n", pustrDeviceName->Buffer);
+
+ /* Allocate a GRAPHICS_DEVICE structure */
+ pGraphicsDevice = ExAllocatePoolWithTag(PagedPool,
+ sizeof(GRAPHICS_DEVICE),
+ GDITAG_GDEVICE);
+ if (!pGraphicsDevice)
+ {
+ DPRINT1("ExAllocatePoolWithTag failed\n");
+ return NULL;
+ }
+
+ /* Try to open the driver */
+ Status = IoGetDeviceObjectPointer(pustrDeviceName,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ &pFileObject,
+ &pDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not open driver, 0x%lx\n", Status);
+ ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
+ return NULL;
+ }
+
+ /* Enable the device */
+ EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cj);
+
+ /* Copy the device and file object pointers */
+ pGraphicsDevice->DeviceObject = pDeviceObject;
+ pGraphicsDevice->FileObject = pFileObject;
+
+ /* Copy device name */
+ wcsncpy(pGraphicsDevice->szNtDeviceName,
+ pustrDeviceName->Buffer,
+ sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR));
+
+ /* Create a win device name (FIXME: virtual devices!) */
+ swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum);
+
+ /* Allocate a buffer for the strings */
+ cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
+ pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP);
+ if (!pwsz)
+ {
+ DPRINT1("Could not allocate string buffer\n");
+ ASSERT(FALSE); // FIXME
+ }
+
+ /* Copy display driver names */
+ pGraphicsDevice->pDiplayDrivers = pwsz;
+ RtlCopyMemory(pGraphicsDevice->pDiplayDrivers,
+ pustrDiplayDrivers->Buffer,
+ pustrDiplayDrivers->Length);
+
+ /* Copy description */
+ pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR);
+ RtlCopyMemory(pGraphicsDevice->pwszDescription,
+ pustrDescription->Buffer,
+ pustrDescription->Length + sizeof(WCHAR));
+
+ /* Initialize the pdevmodeInfo list and default index */
+ pGraphicsDevice->pdevmodeInfo = NULL;
+ pGraphicsDevice->iDefaultMode = 0;
+ pGraphicsDevice->iCurrentMode = 0;
+
+ // FIXME: initialize state flags
+ pGraphicsDevice->StateFlags = 0;
+
+ /* Loop through the driver names
+ * This is a REG_MULTI_SZ string */
+ for (; *pwsz; pwsz += wcslen(pwsz) + 1)
+ {
+ DPRINT1("trying driver: %ls\n", pwsz);
+ /* Try to load the display driver */
+ pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY);
+ if (!pldev)
+ {
+ DPRINT1("Could not load driver: '%ls'\n", pwsz);
+ continue;
+ }
+
+ /* Get the mode list from the driver */
+ pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject);
+ if (!pdminfo)
+ {
+ DPRINT1("Could not get mode list for '%ls'\n", pwsz);
+ continue;
+ }
+
+ /* Attach the mode info to the device */
+ pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
+ pGraphicsDevice->pdevmodeInfo = pdminfo;
+
+ /* Count DEVMODEs */
+ pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
+ for (pdm = pdminfo->adevmode;
+ pdm + 1 <= pdmEnd;
+ pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
+ {
+ cModes++;
+ }
+
+ // FIXME: release the driver again until it's used?
+ }
+
+ if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
+ {
+ DPRINT1("No devmodes\n");
+ ExFreePool(pGraphicsDevice);
+ return NULL;
+ }
+
+ /* Allocate an index buffer */
+ pGraphicsDevice->cDevModes = cModes;
+ pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
+ cModes * sizeof(DEVMODEENTRY),
+ GDITAG_GDEVICE);
+ if (!pGraphicsDevice->pDevModeList)
+ {
+ DPRINT1("No devmode list\n");
+ ExFreePool(pGraphicsDevice);
+ return NULL;
+ }
+
+ /* Loop through all DEVMODEINFOs */
+ for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0;
+ pdminfo;
+ pdminfo = pdminfo->pdmiNext)
+ {
+ /* Calculate End of the DEVMODEs */
+ pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
+
+ /* Loop through the DEVMODEs */
+ for (pdm = pdminfo->adevmode;
+ pdm + 1 <= pdmEnd;
+ pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
+ {
+ /* Compare with the default entry */
+ if (pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
+ pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
+ pdm->dmPelsHeight == pdmDefault->dmPelsHeight &&
+ pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency)
+ {
+ pGraphicsDevice->iDefaultMode = i;
+ pGraphicsDevice->iCurrentMode = i;
+ DPRINT1("Found default entry: %ld '%ls'\n", i, pdm->dmDeviceName);
+ }
+
+ /* Initialize the entry */
+ pGraphicsDevice->pDevModeList[i].dwFlags = 0;
+ pGraphicsDevice->pDevModeList[i].pdm = pdm;
+ i++;
+ }
+ }
+
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemGraphicsDeviceList);
+
+ /* Insert the device into the global list */
+ pGraphicsDevice->pNextGraphicsDevice = gpGraphicsDeviceLast;
+ gpGraphicsDeviceLast = pGraphicsDevice;
+ if (!gpGraphicsDeviceFirst)
+ gpGraphicsDeviceFirst = pGraphicsDevice;
+
+ /* Increment device number */
+ giDevNum++;
+
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemGraphicsDeviceList);
+ DPRINT1("Prepared %ld modes for %ls\n", cModes, pGraphicsDevice->pwszDescription);
+
+ return pGraphicsDevice;
+}
+
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpFindGraphicsDevice(
+ PUNICODE_STRING pustrDevice,
+ ULONG iDevNum,
+ DWORD dwFlags)
+{
+ UNICODE_STRING ustrCurrent;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ ULONG i;
+
+ /* Lock list */
+ EngAcquireSemaphore(ghsemGraphicsDeviceList);
+
+ if (pustrDevice)
+ {
+ /* Loop through the list of devices */
+ for (pGraphicsDevice = gpGraphicsDeviceFirst;
+ pGraphicsDevice;
+ pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
+ {
+ /* Compare the device name */
+ RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
+ if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE))
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Loop through the list of devices */
+ for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
+ pGraphicsDevice && i < iDevNum;
+ pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++);
+ }
+
+ /* Unlock list */
+ EngReleaseSemaphore(ghsemGraphicsDeviceList);
+
+ return pGraphicsDevice;
+}
+
+
static
NTSTATUS
EngpFileIoRequest(
/* Initialize an event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
- /* Build IPR */
+ /* Build IRP */
liStartOffset.QuadPart = ullStartOffset;
pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
pDeviceObject,
/* Initialize an event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
- /* Build IO control IPR */
+ /* Build IO control IRP */
pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode,
pDeviceObject,
lpInBuffer,
NTAPI
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
{
- HPALETTE hpal = NULL;
-
ASSERT(pebo);
ASSERT(pbrush);
ASSERT(pdc);
pebo->crCurrentText = pdc->pdcattr->crForegroundClr;
pebo->psurfTrg = pdc->dclevel.pSurface;
-// ASSERT(pebo->psurfTrg); // FIXME: some dcs don't have a surface
+ ASSERT(pebo->psurfTrg);
+ ASSERT(pebo->psurfTrg->ppal);
- if (pebo->psurfTrg)
- hpal = pebo->psurfTrg->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
- pebo->ppalSurf = PALETTE_ShareLockPalette(hpal);
- if (!pebo->ppalSurf)
- pebo->ppalSurf = &gpalRGB;
+ pebo->ppalSurf = pebo->psurfTrg->ppal;
+ GDIOBJ_IncrementShareCount(&pebo->ppalSurf->BaseObject);
if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
{
pebo->ulRGBColor = crColor;
/* Initialize an XLATEOBJ RGB -> surface */
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, pebo->ppalSurf, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo,
+ &gpalRGB,
+ pebo->ppalSurf,
+ pebo->crCurrentBack,
+ 0,
+ 0);
/* Translate the brush color to the target format */
iSolidColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
pebo->BrushObject.pvRbrush = NULL;
}
- if (pebo->ppalSurf != &gpalRGB)
- PALETTE_ShareUnlockPalette(pebo->ppalSurf);
+ PALETTE_ShareUnlockPalette(pebo->ppalSurf);
}
VOID
ULONG lWidth;
/* Calculate width in bytes of the realized brush */
- lWidth = DIB_GetDIBWidthBytes(psoPattern->sizlBitmap.cx,
+ lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx,
BitsPerFormat(psoDst->iBitmapFormat));
/* Allocate a bitmap */
PPDEVOBJ ppdev = NULL;
EXLATEOBJ exlo;
- // FIXME: all EBRUSHOBJs need a surface, see EBRUSHOBJ_vInit
- if (!pebo->psurfTrg)
- {
- DPRINT1("Pattern brush has no target surface!\n");
- return FALSE;
- }
+ /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
+ ASSERT(pebo->psurfTrg);
ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev;
psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern);
ASSERT(psurfPattern);
+ ASSERT(psurfPattern->ppal);
/* FIXME: implement mask */
psurfMask = NULL;
/* Initialize XLATEOBJ for the brush */
- EXLATEOBJ_vInitBrushXlate(&exlo,
- pebo->pbrush,
- pebo->psurfTrg,
- pebo->crCurrentText,
- pebo->crCurrentBack);
+ EXLATEOBJ_vInitialize(&exlo,
+ psurfPattern->ppal,
+ pebo->psurfTrg->ppal,
+ 0,
+ pebo->crCurrentBack,
+ pebo->crCurrentText);
/* Create the realization */
bResult = pfnRealzizeBrush(&pebo->BrushObject,
{
/* Driver needs to support DrvCopyBits, else we can't do anything */
SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
- if (!(psurfDest->flHooks & HOOK_COPYBITS))
+ if (!(psurfDest->flags & HOOK_COPYBITS))
{
return FALSE;
}
/* Allocate a temporary bitmap */
BitmapSize.cx = DestRect->right - DestRect->left;
BitmapSize.cy = DestRect->bottom - DestRect->top;
- Width = DIB_GetDIBWidthBytes(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat));
+ Width = WIDTH_BYTES_ALIGN32(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat));
EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width,
psoDest->iBitmapFormat,
BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
&ClippedDestRect, &SrcPoint))
{
EngDeleteClip(EnterLeave->TrivialClipObj);
- EngFreeMem((*ppsoOutput)->pvBits);
EngUnlockSurface(*ppsoOutput);
EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
return FALSE;
if (NULL != *ppsoOutput)
{
SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj);
- if (0 != (psurfOutput->flHooks & HOOK_SYNCHRONIZE))
+ if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE))
{
if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface)
{
Result = TRUE;
}
}
- EngFreeMem(EnterLeave->OutputObj->pvBits);
EngUnlockSurface(EnterLeave->OutputObj);
EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
EngDeleteClip(EnterLeave->TrivialClipObj);
psurf = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
ASSERT(psurf);
- SURFACE_LockBitmapBits(psurf);
- MouseSafetyOnDrawStart(
- psoDest,
- pco->rclBounds.left,
- pco->rclBounds.top,
- pco->rclBounds.right,
- pco->rclBounds.bottom);
- if(psurf->flHooks & HOOK_GRADIENTFILL)
+ if(psurf->flags & HOOK_GRADIENTFILL)
{
Ret = GDIDEVFUNCS(psoDest).GradientFill(
psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh,
Ret = EngGradientFill(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents,
pptlDitherOrg, ulMode);
}
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurf);
return Ret;
}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Support for logical devices
+ * FILE: subsystems/win32/win32k/eng/ldevobj.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include <win32k.h>
+
+#include <intrin.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#ifndef RVA_TO_ADDR
+#define RVA_TO_ADDR(Base,Rva) ((PVOID)(((ULONG_PTR)(Base)) + (Rva)))
+#endif
+
+/** Globals *******************************************************************/
+
+HSEMAPHORE ghsemLDEVList;
+LDEVOBJ *gpldevHead = NULL;
+LDEVOBJ *gpldevWin32k = NULL;
+
+
+/** Private functions *********************************************************/
+
+BOOL
+NTAPI
+InitLDEVImpl()
+{
+ /* Initialize the loader lock */
+ ghsemLDEVList = EngCreateSemaphore();
+ if (!ghsemLDEVList)
+ {
+ return FALSE;
+ }
+
+ /* Allocate a LDEVOBJ for win32k */
+ gpldevWin32k = ExAllocatePoolWithTag(PagedPool,
+ sizeof(LDEVOBJ) +
+ sizeof(SYSTEM_GDI_DRIVER_INFORMATION),
+ GDITAG_LDEV);
+ if (!gpldevWin32k)
+ {
+ return FALSE;
+ }
+
+ /* Initialize the LDEVOBJ for win32k */
+ gpldevWin32k->pldevNext = NULL;
+ gpldevWin32k->pldevPrev = NULL;
+ gpldevWin32k->ldevtype = LDEV_DEVICE_DISPLAY;
+ gpldevWin32k->cRefs = 1;
+ gpldevWin32k->ulDriverVersion = GDI_ENGINE_VERSION;
+ gpldevWin32k->pGdiDriverInfo = (PVOID)(gpldevWin32k + 1);
+ RtlInitUnicodeString(&gpldevWin32k->pGdiDriverInfo->DriverName,
+ L"\\SystemRoot\\System32\\win32k.sys");
+ gpldevWin32k->pGdiDriverInfo->ImageAddress = &__ImageBase;
+ gpldevWin32k->pGdiDriverInfo->SectionPointer = NULL;
+ gpldevWin32k->pGdiDriverInfo->EntryPoint = (PVOID)DriverEntry;
+ gpldevWin32k->pGdiDriverInfo->ExportSectionPointer = NULL;
+ gpldevWin32k->pGdiDriverInfo->ImageLength = 0; // FIXME;
+
+ return TRUE;
+}
+
+PLDEVOBJ
+NTAPI
+LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype)
+{
+ PLDEVOBJ pldev;
+
+ /* Allocate the structure from paged pool */
+ pldev = ExAllocatePoolWithTag(PagedPool, sizeof(LDEVOBJ), GDITAG_LDEV);
+ if (!pldev)
+ {
+ DPRINT1("Failed to allocate LDEVOBJ.\n");
+ return NULL;
+ }
+
+ /* Zero out the structure */
+ RtlZeroMemory(pldev, sizeof(LDEVOBJ));
+
+ /* Set the ldevtype */
+ pldev->ldevtype = ldevtype;
+
+ return pldev;
+}
+
+VOID
+NTAPI
+LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev)
+{
+ /* Make sure we don't have a driver loaded */
+ ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
+
+ /* Free the memory */
+ ExFreePoolWithTag(pldev, TAG_LDEV);
+}
+
+PDEVMODEINFO
+NTAPI
+LDEVOBJ_pdmiGetModes(
+ PLDEVOBJ pldev,
+ HANDLE hDriver)
+{
+ ULONG cbSize, cbFull;
+ PDEVMODEINFO pdminfo;
+
+ DPRINT("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver);
+
+ /* Call the driver to get the required size */
+ cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
+ if (!cbSize)
+ {
+ DPRINT1("DrvGetModes returned 0\n");
+ return NULL;
+ }
+
+ /* Add space for the header */
+ cbFull = cbSize + FIELD_OFFSET(DEVMODEINFO, adevmode);
+
+ /* Allocate a buffer for the DEVMODE array */
+ pdminfo = ExAllocatePoolWithTag(PagedPool, cbFull, GDITAG_DEVMODE);
+ if (!pdminfo)
+ {
+ DPRINT1("Could not allocate devmodeinfo\n");
+ return NULL;
+ }
+
+ pdminfo->pldev = pldev;
+ pdminfo->cbdevmode = cbSize;
+
+ /* Call the driver again to fill the buffer */
+ cbSize = pldev->pfn.GetModes(hDriver, cbSize, pdminfo->adevmode);
+ if (!cbSize)
+ {
+ /* Could not get modes */
+ DPRINT1("returned size %ld(%ld)\n", cbSize, pdminfo->cbdevmode);
+ ExFreePool(pdminfo);
+ pdminfo = NULL;
+ }
+
+ return pdminfo;
+}
+
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadImage(
+ IN PLDEVOBJ pldev,
+ PUNICODE_STRING pstrPathName)
+{
+ PSYSTEM_GDI_DRIVER_INFORMATION pDriverInfo;
+ NTSTATUS Status;
+ ULONG cbSize;
+
+ /* Make sure no image is loaded yet */
+ ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
+
+ /* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */
+ cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pstrPathName->Length;
+ pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV);
+ if (!pDriverInfo)
+ {
+ DPRINT1("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n");
+ return FALSE;
+ }
+
+ /* Initialize the UNICODE_STRING and copy the driver name */
+ RtlInitEmptyUnicodeString(&pDriverInfo->DriverName,
+ (PWSTR)(pDriverInfo + 1),
+ pstrPathName->Length);
+ RtlCopyUnicodeString(&pDriverInfo->DriverName, pstrPathName);
+
+ /* Try to load the driver */
+ Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation,
+ pDriverInfo,
+ sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to load a GDI driver: '%S', Status = 0x%lx\n",
+ pstrPathName->Buffer, Status);
+
+ /* Free the allocated memory */
+ ExFreePoolWithTag(pDriverInfo, TAG_LDEV);
+ return FALSE;
+ }
+
+ /* Set the driver info */
+ pldev->pGdiDriverInfo = pDriverInfo;
+
+ /* Return success. */
+ return TRUE;
+}
+
+VOID
+NTAPI
+LDEVOBJ_vUnloadImage(
+ IN PLDEVOBJ pldev)
+{
+ NTSTATUS Status;
+
+ /* Make sure we have a driver info */
+ ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+ /* Check if we have loaded a driver */
+ if (pldev->pfn.DisableDriver)
+ {
+ /* Call the unload function */
+ pldev->pfn.DisableDriver();
+ }
+
+ /* Unload the driver */
+ Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
+ &pldev->pGdiDriverInfo->ImageAddress,
+ sizeof(HANDLE));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to unload the driver, this is bad.\n");
+ }
+
+ /* Free the driver info structure */
+ ExFreePoolWithTag(pldev->pGdiDriverInfo, GDITAG_LDEV);
+ pldev->pGdiDriverInfo = NULL;
+}
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadDriver(
+ IN PLDEVOBJ pldev)
+{
+ PFN_DrvEnableDriver pfnEnableDriver;
+ DRVENABLEDATA ded;
+ ULONG i;
+
+ /* Make sure we have a driver info */
+ ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+ /* Call the drivers DrvEnableDriver function */
+ RtlZeroMemory(&ded, sizeof(ded));
+ pfnEnableDriver = pldev->pGdiDriverInfo->EntryPoint;
+ if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded))
+ {
+ DPRINT1("DrvEnableDriver failed\n");
+
+ /* Unload the image. */
+ LDEVOBJ_vUnloadImage(pldev);
+ return FALSE;
+ }
+
+ /* Copy the returned driver version */
+ pldev->ulDriverVersion = ded.iDriverVersion;
+
+ /* Fill the driver function array */
+ for (i = 0; i < ded.c; i++)
+ {
+ pldev->apfn[ded.pdrvfn[i].iFunc] = ded.pdrvfn[i].pfn;
+ }
+
+ /* Return success. */
+ return TRUE;
+}
+
+
+PVOID
+NTAPI
+LDEVOBJ_pvFindImageProcAddress(
+ IN PLDEVOBJ pldev,
+ IN LPSTR pszProcName)
+{
+ PVOID pvImageBase;
+ PIMAGE_EXPORT_DIRECTORY pExportDir;
+ PVOID pvProcAdress = NULL;
+ PUSHORT pOrdinals;
+ PULONG pNames, pAddresses;
+ ULONG i, cbSize;
+
+ /* Make sure we have a driver info */
+ ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
+
+ /* Get the pointer to the export directory */
+ pvImageBase = pldev->pGdiDriverInfo->ImageAddress;
+ pExportDir = RtlImageDirectoryEntryToData(pvImageBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &cbSize);
+ if (!pExportDir)
+ {
+ return NULL;
+ }
+
+ /* Get pointers to some tables */
+ pNames = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNames);
+ pOrdinals = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNameOrdinals);
+ pAddresses = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfFunctions);
+
+ /* Loop the export table */
+ for (i = 0; i < pExportDir->NumberOfNames; i++)
+ {
+ /* Compare the name */
+ if (_stricmp(pszProcName, RVA_TO_ADDR(pvImageBase, pNames[i])) == 0)
+ {
+ /* Found! Calculate the procedure address */
+ pvProcAdress = RVA_TO_ADDR(pvImageBase, pAddresses[pOrdinals[i]]);
+ break;
+ }
+ }
+
+ /* Return the address */
+ return pvProcAdress;
+}
+
+PLDEVOBJ
+NTAPI
+EngLoadImageEx(
+ LPWSTR pwszDriverName,
+ ULONG ldevtype)
+{
+ WCHAR acwBuffer[MAX_PATH];
+ PLDEVOBJ pldev;
+ UNICODE_STRING strDriverName;
+ ULONG cwcLength;
+ LPWSTR pwsz;
+
+ DPRINT("EngLoadImageEx(%ls, %ld)\n", pwszDriverName, ldevtype);
+ ASSERT(pwszDriverName);
+
+ /* Initialize buffer for the the driver name */
+ RtlInitEmptyUnicodeString(&strDriverName, acwBuffer, sizeof(acwBuffer));
+
+ /* Start path with systemroot */
+ RtlAppendUnicodeToString(&strDriverName, L"\\SystemRoot\\System32\\");
+
+ /* Get Length of given string */
+ cwcLength = wcslen(pwszDriverName);
+
+ /* Check if we have a system32 path given */
+ pwsz = pwszDriverName + cwcLength;
+ while (pwsz > pwszDriverName)
+ {
+ if (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0)
+ {
+ /* Driver name starts after system32 */
+ pwsz += 10;
+ break;
+ }
+ pwsz--;
+ }
+
+ /* Append the driver name */
+ RtlAppendUnicodeToString(&strDriverName, pwsz);
+
+ /* MSDN says "The driver must include this suffix in the pwszDriver string."
+ But in fact it's optional. */
+ if (_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0)
+ {
+ /* Append the .dll suffix */
+ RtlAppendUnicodeToString(&strDriverName, L".dll");
+ }
+
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemLDEVList);
+
+ /* Search the List of LDEVS for the driver name */
+ for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext)
+ {
+ /* Check if the ldev is associated with a file */
+ if (pldev->pGdiDriverInfo)
+ {
+ /* Check for match (case insensative) */
+ if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1))
+ {
+ /* Image found in LDEV list */
+ break;
+ }
+ }
+ }
+
+ /* Did we find one? */
+ if (!pldev)
+ {
+ /* No, allocate a new LDEVOBJ */
+ pldev = LDEVOBJ_AllocLDEV(ldevtype);
+ if (!pldev)
+ {
+ DPRINT1("Could not allocate LDEV\n");
+ goto leave;
+ }
+
+ /* Load the image */
+ if (!LDEVOBJ_bLoadImage(pldev, &strDriverName))
+ {
+ LDEVOBJ_vFreeLDEV(pldev);
+ pldev = NULL;
+ DPRINT1("LDEVOBJ_bLoadImage failed\n");
+ goto leave;
+ }
+
+ /* Shall we load a driver? */
+ if (ldevtype != LDEV_IMAGE)
+ {
+ /* Load the driver */
+ if (!LDEVOBJ_bLoadDriver(pldev))
+ {
+ DPRINT1("LDEVOBJ_bLoadDriver failed\n");
+ LDEVOBJ_vFreeLDEV(pldev);
+ pldev = NULL;
+ goto leave;
+ }
+ }
+
+ /* Insert the LDEV into the global list */
+ pldev->pldevPrev = NULL;
+ pldev->pldevNext = gpldevHead;
+ gpldevHead = pldev;
+ }
+
+ /* Increase ref count */
+ pldev->cRefs++;
+
+leave:
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemLDEVList);
+
+ DPRINT("EngLoadImageEx returning %p\n", pldev);
+
+ return pldev;
+}
+
+
+/** Exported functions ********************************************************/
+
+HANDLE
+APIENTRY
+EngLoadImage(
+ LPWSTR pwszDriverName)
+{
+ return (HANDLE)EngLoadImageEx(pwszDriverName, LDEV_IMAGE);
+}
+
+
+VOID
+APIENTRY
+EngUnloadImage(
+ IN HANDLE hModule)
+{
+ PLDEVOBJ pldev = (PLDEVOBJ)hModule;
+
+ /* Make sure the LDEV is in the list */
+ ASSERT(pldev->pldevPrev || pldev->pldevNext);
+
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemLDEVList);
+
+ /* Decrement reference count */
+ pldev->cRefs--;
+
+ /* No more references left? */
+ if (pldev->cRefs == 0)
+ {
+ /* Remove ldev from the list */
+ if (pldev->pldevPrev)
+ pldev->pldevPrev->pldevNext = pldev->pldevNext;
+ if (pldev->pldevNext)
+ pldev->pldevNext->pldevPrev = pldev->pldevPrev;
+
+ /* Unload the image */
+ LDEVOBJ_vUnloadImage(pldev);
+ }
+
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemLDEVList);
+}
+
+
+PVOID
+APIENTRY
+EngFindImageProcAddress(
+ IN HANDLE hModule,
+ IN LPSTR lpProcName)
+{
+ PLDEVOBJ pldev = (PLDEVOBJ)hModule;
+
+ ASSERT(gpldevWin32k != NULL);
+
+ /* Check if win32k is requested */
+ if (!pldev)
+ {
+ pldev = gpldevWin32k;
+ }
+
+ /* Check if the drivers entry point is requested */
+ if (_strnicmp(lpProcName, "DrvEnableDriver", 15) == 0)
+ {
+ return pldev->pGdiDriverInfo->EntryPoint;
+ }
+
+ /* Try to find the address */
+ return LDEVOBJ_pvFindImageProcAddress(pldev, lpProcName);
+}
+
if (b.left == b.right) b.right++;
if (b.top == b.bottom) b.bottom++;
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, x1, y1, x2, y2);
-
- if (psurfDest->flHooks & HOOK_LINETO)
+ if (psurfDest->flags & HOOK_LINETO)
{
/* Call the driver's DrvLineTo */
ret = GDIDEVFUNCS(psoDest).LineTo(
}
#if 0
- if (! ret && (psurfDest->flHooks & HOOK_STROKEPATH))
+ if (! ret && (psurfDest->flags & HOOK_STROKEPATH))
{
/* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
}
ret = EngLineTo(psoDest, ClipObj, pbo, x1, y1, x2, y2, RectBounds, Mix);
}
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
return ret;
}
* PROJECT: ReactOS kernel
* PURPOSE: Functions for mapping files and sections
* FILE: subsys/win32k/eng/device.c
- * PROGRAMER:
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include <win32k.h>
#define NDEBUG
#include <debug.h>
+// HACK!!!
+#define MmMapViewInSessionSpace MmMapViewInSystemSpace
+#define MmUnmapViewInSessionSpace MmUnmapViewInSystemSpace
+
+typedef struct _ENGSECTION
+{
+ PVOID pvSectionObject;
+ PVOID pvMappedBase;
+ SIZE_T cjViewSize;
+ ULONG ulTag;
+} ENGSECTION, *PENGSECTION;
+
+typedef struct _FILEVIEW
+{
+ LARGE_INTEGER LastWriteTime;
+ PVOID pvKView;
+ PVOID pvViewFD;
+ SIZE_T cjView;
+ PVOID pSection;
+} FILEVIEW, *PFILEVIEW;
+
+typedef struct _FONTFILEVIEW
+{
+ FILEVIEW;
+ DWORD reserved[2];
+ PWSTR pwszPath;
+ SIZE_T ulRegionSize;
+ ULONG cKRefCount;
+ ULONG cRefCountFD;
+ PVOID pvSpoolerBase;
+ DWORD dwSpoolerPid;
+} FONTFILEVIEW, *PFONTFILEVIEW;
+
+enum
+{
+ FVF_SYSTEMROOT = 1,
+ FVF_READONLY = 2,
+ FVF_FONTFILE = 4,
+};
+
+HANDLE ghSystem32Directory;
+HANDLE ghRootDirectory;
+
+
+PVOID
+NTAPI
+EngCreateSection(
+ IN ULONG fl,
+ IN SIZE_T cjSize,
+ IN ULONG ulTag)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection;
+ PVOID pvSectionObject;
+ LARGE_INTEGER liSize;
+
+ /* Allocate a section object */
+ pSection = EngAllocMem(0, sizeof(ENGSECTION), 'stsU');
+ if (!pSection) return NULL;
+
+ liSize.QuadPart = cjSize;
+ Status = MmCreateSection(&pvSectionObject,
+ SECTION_ALL_ACCESS,
+ NULL,
+ &liSize,
+ PAGE_READWRITE,
+ SEC_COMMIT,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create a section Status=0x%x\n", Status);
+ EngFreeMem(pSection);
+ return NULL;
+ }
+
+ /* Set the fields of the section */
+ pSection->ulTag = ulTag;
+ pSection->pvSectionObject = pvSectionObject;
+ pSection->pvMappedBase = NULL;
+ pSection->cjViewSize = cjSize;
+
+ return pSection;
+}
+
+
+BOOL
+APIENTRY
+EngMapSection(
+ IN PVOID pvSection,
+ IN BOOL bMap,
+ IN HANDLE hProcess,
+ OUT PVOID* pvBaseAddress)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection = pvSection;
+ PEPROCESS pepProcess;
+
+ /* Get a pointer to the process */
+ Status = ObReferenceObjectByHandle(hProcess,
+ PROCESS_VM_OPERATION,
+ NULL,
+ KernelMode,
+ (PVOID*)&pepProcess,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess, Status);
+ return FALSE;
+ }
+
+ if (bMap)
+ {
+ /* Make sure the section isn't already mapped */
+ ASSERT(pSection->pvMappedBase == NULL);
+
+ /* Map the section into the process address space */
+ Status = MmMapViewOfSection(pSection->pvSectionObject,
+ pepProcess,
+ &pSection->pvMappedBase,
+ 0,
+ pSection->cjViewSize,
+ NULL,
+ &pSection->cjViewSize,
+ 0,
+ 0,
+ PAGE_READWRITE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a section Status=0x%x\n", Status);
+ }
+ }
+ else
+ {
+ /* Make sure the section is mapped */
+ ASSERT(pSection->pvMappedBase);
+
+ /* Unmap the section from the process address space */
+ Status = MmUnmapViewOfSection(pepProcess, pSection->pvMappedBase);
+ if (NT_SUCCESS(Status))
+ {
+ pSection->pvMappedBase = NULL;
+ }
+ else
+ {
+ DPRINT1("Failed to unmap a section @ &p Status=0x%x\n",
+ pSection->pvMappedBase, Status);
+ }
+ }
+
+ /* Dereference the process */
+ ObDereferenceObject(pepProcess);
+
+ /* Set the new mapping base and return bool status */
+ *pvBaseAddress = pSection->pvMappedBase;
+ return NT_SUCCESS(Status);
+}
+
+BOOL
+APIENTRY
+EngFreeSectionMem(
+ IN PVOID pvSection OPTIONAL,
+ IN PVOID pvMappedBase OPTIONAL)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection = pvSection;
+ BOOL bResult = TRUE;
+
+ /* Did the caller give us a mapping base? */
+ if (pvMappedBase)
+ {
+ Status = MmUnmapViewInSessionSpace(pvMappedBase);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
+ bResult = FALSE;
+ }
+ }
+
+ /* Check if we should free the section as well */
+ if (pSection)
+ {
+ /* Dereference the kernel section */
+ ObDereferenceObject(pSection->pvSectionObject);
+
+ /* Finally free the section memory itself */
+ EngFreeMem(pSection);
+ }
+
+ return bResult;
+}
+
+PVOID
+APIENTRY
+EngAllocSectionMem(
+ OUT PVOID *ppvSection,
+ IN ULONG fl,
+ IN SIZE_T cjSize,
+ IN ULONG ulTag)
+{
+ NTSTATUS Status;
+ PENGSECTION pSection;
+
+ /* Check parameter */
+ if (cjSize == 0) return NULL;
+
+ /* Allocate a section object */
+ pSection = EngCreateSection(fl, cjSize, ulTag);
+ if (!pSection)
+ {
+ *ppvSection = NULL;
+ return NULL;
+ }
+
+ /* Map the section in session space */
+ Status = MmMapViewInSessionSpace(pSection->pvSectionObject,
+ &pSection->pvMappedBase,
+ &pSection->cjViewSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a section Status=0x%x\n", Status);
+ *ppvSection = NULL;
+ EngFreeSectionMem(pSection, NULL);
+ return NULL;
+ }
+
+ if (fl & FL_ZERO_MEMORY)
+ {
+ RtlZeroMemory(pSection->pvMappedBase, cjSize);
+ }
+
+ /* Set section pointer and return base address */
+ *ppvSection = pSection;
+ return pSection->pvMappedBase;
+}
+
+
+PFILEVIEW
+NTAPI
+EngLoadModuleEx(
+ LPWSTR pwsz,
+ ULONG cjSizeOfModule,
+ FLONG fl)
+{
+ PFILEVIEW pFileView = NULL;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hRootDir;
+ UNICODE_STRING ustrFileName;
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_BASIC_INFORMATION FileInformation;
+ HANDLE hFile;
+ NTSTATUS Status;
+ LARGE_INTEGER liSize;
+
+ if (fl & FVF_FONTFILE)
+ {
+ pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG');
+ }
+ else
+ {
+ pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg');
+ }
+
+ /* Check for success */
+ if (!pFileView) return NULL;
+
+ /* Check if the file is relative to system32 */
+ if (fl & FVF_SYSTEMROOT)
+ {
+ hRootDir = ghSystem32Directory;
+ }
+ else
+ {
+ hRootDir = ghRootDirectory;
+ }
+
+ /* Initialize unicode string and object attributes */
+ RtlInitUnicodeString(&ustrFileName, pwsz);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ustrFileName,
+ OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
+ hRootDir,
+ NULL);
+
+ /* Now open the file */
+ Status = ZwCreateFile(&hFile,
+ FILE_READ_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ FILE_OPEN,
+ FILE_NON_DIRECTORY_FILE,
+ NULL,
+ 0);
+
+ Status = ZwQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileInformation,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ if (NT_SUCCESS(Status))
+ {
+ pFileView->LastWriteTime = FileInformation.LastWriteTime;
+ }
+
+ /* Create a section from the file */
+ liSize.QuadPart = cjSizeOfModule;
+ Status = MmCreateSection(&pFileView->pSection,
+ SECTION_ALL_ACCESS,
+ NULL,
+ cjSizeOfModule ? &liSize : NULL,
+ fl & FVF_READONLY ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE,
+ SEC_COMMIT,
+ hFile,
+ NULL);
+
+ /* Close the file handle */
+ ZwClose(hFile);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create a section Status=0x%x\n", Status);
+ EngFreeMem(pFileView);
+ return NULL;
+ }
+
+
+ pFileView->pvKView = NULL;
+ pFileView->pvViewFD = NULL;
+ pFileView->cjView = 0;
+
+ return pFileView;
+}
+
HANDLE
APIENTRY
EngLoadModule(LPWSTR pwsz)
{
- UNIMPLEMENTED;
- return NULL;
+ /* Forward to EngLoadModuleEx */
+ return (HANDLE)EngLoadModuleEx(pwsz, 0, FVF_READONLY | FVF_SYSTEMROOT);
}
HANDLE
IN LPWSTR pwsz,
IN ULONG cjSizeOfModule)
{
- // www.osr.com/ddk/graphics/gdifncs_98rr.htm
- UNIMPLEMENTED;
- return NULL;
+ /* Forward to EngLoadModuleEx */
+ return (HANDLE)EngLoadModuleEx(pwsz, cjSizeOfModule, FVF_SYSTEMROOT);
}
PVOID
IN HANDLE h,
OUT PULONG pulSize)
{
- // www.osr.com/ddk/graphics/gdifncs_9b1j.htm
- UNIMPLEMENTED;
- return NULL;
+ PFILEVIEW pFileView = (PFILEVIEW)h;
+ NTSTATUS Status;
+
+ pFileView->cjView = 0;
+
+ /* Map the section in session space */
+ Status = MmMapViewInSessionSpace(pFileView->pSection,
+ &pFileView->pvKView,
+ &pFileView->cjView);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a section Status=0x%x\n", Status);
+ *pulSize = 0;
+ return NULL;
+ }
+
+ *pulSize = pFileView->cjView;
+ return pFileView->pvKView;
}
VOID
APIENTRY
-EngFreeModule (IN HANDLE h)
+EngFreeModule(IN HANDLE h)
{
- // www.osr.com/ddk/graphics/gdifncs_9fzb.htm
- UNIMPLEMENTED;
+ PFILEVIEW pFileView = (PFILEVIEW)h;
+ NTSTATUS Status;
+
+ /* Unmap the section */
+ Status = MmUnmapViewInSessionSpace(pFileView->pvKView);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status);
+ ASSERT(FALSE);
+ }
+
+ /* Dereference the section */
+ ObDereferenceObject(pFileView->pSection);
+
+ /* Free the file view memory */
+ EngFreeMem(pFileView);
}
PVOID
IN ULONG cjSize,
OUT ULONG_PTR *piFile)
{
- UNIMPLEMENTED;
- return NULL;
+ HANDLE hModule;
+ PVOID pvBase;
+
+ /* Load the file */
+ hModule = EngLoadModuleEx(pwsz, 0, 0);
+ if (!hModule)
+ {
+ *piFile = 0;
+ return NULL;
+ }
+
+ /* Map the file */
+ pvBase = EngMapModule(hModule, &cjSize);
+ if (!pvBase)
+ {
+ EngFreeModule(hModule);
+ hModule = NULL;
+ }
+
+ /* Set iFile and return mapped base */
+ *piFile = (ULONG_PTR)hModule;
+ return pvBase;
}
BOOL
EngUnmapFile(
IN ULONG_PTR iFile)
{
- UNIMPLEMENTED;
- return FALSE;
+ HANDLE hModule = (HANDLE)iFile;
+
+ EngFreeModule(hModule);
+
+ return TRUE;
}
// www.osr.com/ddk/graphics/gdifncs_09wn.htm
EngUnmapFontFileFD(iFile);
}
-
-
-BOOLEAN
-APIENTRY
-EngMapSection(IN PVOID Section,
- IN BOOLEAN Map,
- IN HANDLE Process,
- IN PVOID* BaseAddress)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-PVOID
-APIENTRY
-EngAllocSectionMem(IN PVOID SectionObject,
- IN ULONG Flags,
- IN SIZE_T MemSize,
- IN ULONG Tag)
-{
- UNIMPLEMENTED;
- return NULL;
-}
-
-
-BOOLEAN
-APIENTRY
-EngFreeSectionMem(IN PVOID SectionObject OPTIONAL,
- IN PVOID MappedBase)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
}
/* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */
+ //hSecure = EngSecureMem(NewMem, cj);
return NewMem;
}
HANDLE APIENTRY
EngSecureMem(PVOID Address, ULONG Length)
{
+ return (HANDLE)-1; // HACK!!!
return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE);
}
VOID APIENTRY
EngUnsecureMem(HANDLE Mem)
{
+ if (Mem == (HANDLE)-1) return; // HACK!!!
MmUnsecureVirtualMemory((PVOID) Mem);
}
*/
INT INTERNAL_CALL
MouseSafetyOnDrawStart(
- SURFOBJ *pso,
+ PPDEVOBJ ppdev,
LONG HazardX1,
LONG HazardY1,
LONG HazardX2,
LONG HazardY2)
{
LONG tmp;
- PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- ASSERT(pso != NULL);
-
- ppdev = GDIDEV(pso);
- if (ppdev == NULL)
- {
- return FALSE;
- }
+ ASSERT(ppdev != NULL);
+ ASSERT(ppdev->pSurface != NULL);
pgp = &ppdev->Pointer;
}
if (pgp->Exclude.right >= HazardX1
- && pgp->Exclude.left <= HazardX2
- && pgp->Exclude.bottom >= HazardY1
- && pgp->Exclude.top <= HazardY2)
+ && pgp->Exclude.left <= HazardX2
+ && pgp->Exclude.bottom >= HazardY1
+ && pgp->Exclude.top <= HazardY2)
{
ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
- ppdev->pfnMovePointer(pso, -1, -1, NULL);
+ ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj, -1, -1, NULL);
}
return(TRUE);
*/
INT INTERNAL_CALL
MouseSafetyOnDrawEnd(
- SURFOBJ *pso)
+ PPDEVOBJ ppdev)
{
- PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- ASSERT(pso != NULL);
-
- ppdev = (PDEVOBJ*)pso->hdev;
-
- if (ppdev == NULL)
- {
- return(FALSE);
- }
+ ASSERT(ppdev != NULL);
+ ASSERT(ppdev->pSurface != NULL);
pgp = &ppdev->Pointer;
return FALSE;
}
- ppdev->pfnMovePointer(pso, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude);
+ ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj,
+ gpsi->ptCursor.x,
+ gpsi->ptCursor.y,
+ &pgp->Exclude);
ppdev->SafetyRemoveLevel = 0;
ptlSave.x = rclDest.left - pt.x;
ptlSave.y = rclDest.top - pt.y;
- IntEngBitBltEx(psoDest,
- &pgp->psurfSave->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclDest,
- &ptlSave,
- &ptlSave,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCCOPY),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfSave->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclDest,
+ &ptlSave,
+ &ptlSave,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
}
VOID
rclPointer.bottom = min(pgp->Size.cy, psoDest->sizlBitmap.cy - pt.y);
/* Copy the pixels under the cursor to temporary surface. */
- IntEngBitBltEx(&pgp->psurfSave->SurfObj,
- psoDest,
- NULL,
- NULL,
- NULL,
- &rclPointer,
- (POINTL*)&rclSurf,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCCOPY),
- FALSE);
+ IntEngBitBlt(&pgp->psurfSave->SurfObj,
+ psoDest,
+ NULL,
+ NULL,
+ NULL,
+ &rclPointer,
+ (POINTL*)&rclSurf,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCCOPY));
/* Blt the pointer on the screen. */
if (pgp->psurfColor)
{
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCAND),
- FALSE);
-
- IntEngBitBltEx(psoDest,
- &pgp->psurfColor->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCINVERT),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCAND));
+
+ IntEngBitBlt(psoDest,
+ &pgp->psurfColor->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCINVERT));
}
else
{
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCAND),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCAND));
rclPointer.top += pgp->Size.cy;
- IntEngBitBltEx(psoDest,
- &pgp->psurfMask->SurfObj,
- NULL,
- NULL,
- NULL,
- &rclSurf,
- (POINTL*)&rclPointer,
- NULL,
- NULL,
- NULL,
- ROP3_TO_ROP4(SRCINVERT),
- FALSE);
+ IntEngBitBlt(psoDest,
+ &pgp->psurfMask->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ &rclSurf,
+ (POINTL*)&rclPointer,
+ NULL,
+ NULL,
+ NULL,
+ ROP3_TO_ROP4(SRCINVERT));
}
}
rectl.bottom = sizel.cy;
/* Calculate lDelta for our surfaces. */
- lDelta = DIB_GetDIBWidthBytes(sizel.cx,
+ lDelta = WIDTH_BYTES_ALIGN32(sizel.cx,
BitsPerFormat(pso->iBitmapFormat));
/* Create a bitmap for saving the pixels under the cursor. */
/* Create a bitmap to copy the color bitmap to */
hbmColor = EngCreateBitmap(psoColor->sizlBitmap,
- lDelta,
- pso->iBitmapFormat,
- BMF_TOPDOWN | BMF_NOZEROINIT,
- NULL);
+ lDelta,
+ pso->iBitmapFormat,
+ BMF_TOPDOWN | BMF_NOZEROINIT,
+ NULL);
psurfColor = SURFACE_ShareLockSurface(hbmColor);
if (!psurfColor) goto failure;
prcl->right = prcl->left + pgp->Size.cx;
prcl->bottom = prcl->top + pgp->Size.cy;
}
- }
+ }
else if (prcl != NULL)
{
prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
}
}
-VOID APIENTRY
-IntEngMovePointer(
- IN SURFOBJ *pso,
- IN LONG x,
- IN LONG y,
- IN RECTL *prcl)
-{
- SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
- PPDEVOBJ ppdev = (PPDEVOBJ)pso->hdev;
-
- SURFACE_LockBitmapBits(psurf);
- ppdev->pfnMovePointer(pso, x, y, prcl);
- SURFACE_UnlockBitmapBits(psurf);
-}
-
ULONG APIENTRY
IntEngSetPointerShape(
IN SURFOBJ *pso,
IN FLONG fl)
{
ULONG ulResult = SPS_DECLINE;
- SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
PFN_DrvSetPointerShape pfnSetPointerShape;
PPDEVOBJ ppdev = GDIDEV(pso);
pfnSetPointerShape = GDIDEVFUNCS(pso).SetPointerShape;
- SURFACE_LockBitmapBits(psurf);
if (pfnSetPointerShape)
{
ulResult = pfnSetPointerShape(pso,
ppdev->pfnMovePointer = EngMovePointer;
}
- SURFACE_UnlockBitmapBits(psurf);
-
return ulResult;
}
return 0;
}
- psurf = pdc->dclevel.pSurface;
+ ASSERT(pdc->dctype == DCTYPE_DIRECT);
+ EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
+ /* We're not sure DC surface is the good one */
+ psurf = pdc->ppdev->pSurface;
if (!psurf)
{
DPRINT1("DC has no surface.\n");
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
DC_UnlockDc(pdc);
return 0;
}
{
/* We have one, lock it */
psurfColor = SURFACE_ShareLockSurface(hbmColor);
-
+
if (psurfColor)
{
/* Create an XLATEOBJ, no mono support */
if (psurfMask)
SURFACE_ShareUnlockSurface(psurfMask);
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+
/* Unlock the DC */
DC_UnlockDc(pdc);
DPRINT1("Failed to lock the DC.\n");
return;
}
+ ASSERT(pdc->dctype == DCTYPE_DIRECT);
+
+ /* Acquire PDEV lock */
+ EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
- /* Store the cursor exclude position in the PDEV */
- prcl = &pdc->ppdev->Pointer.Exclude;
+ /* Check if we need to move it */
+ if(pdc->ppdev->SafetyRemoveLevel == 0)
+ {
+ /* Store the cursor exclude position in the PDEV */
+ prcl = &pdc->ppdev->Pointer.Exclude;
+
+ /* Call Eng/Drv function */
+ pdc->ppdev->pfnMovePointer(&pdc->ppdev->pSurface->SurfObj, x, y, prcl);
+ }
- /* Call Eng/Drv function */
- IntEngMovePointer(&pdc->dclevel.pSurface->SurfObj, x, y, prcl);
+ /* Release PDEV lock */
+ EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
/* Unlock the DC */
DC_UnlockDc(pdc);
#define NDEBUG
#include <debug.h>
-static BOOL APIENTRY FillSolidUnlocked(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
+BOOL APIENTRY FillSolid(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
{
LONG y;
ULONG LineWidth;
ASSERT(pso);
ASSERT(pRect);
- MouseSafetyOnDrawStart(pso, pRect->left, pRect->top, pRect->right, pRect->bottom);
LineWidth = pRect->right - pRect->left;
DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom);
for (y = pRect->top; y < pRect->bottom; y++)
DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_HLine(
pso, pRect->left, pRect->right, y, iColor);
}
- MouseSafetyOnDrawEnd(pso);
-
return TRUE;
}
-BOOL APIENTRY FillSolid(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
-{
- SURFACE *psurf;
- BOOL Result;
- psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
- SURFACE_LockBitmapBits(psurf);
- Result = FillSolidUnlocked(pso, pRect, iColor);
- SURFACE_UnlockBitmapBits(psurf);
- return Result;
-}
-
BOOL APIENTRY
EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
BRUSHOBJ *BrushObj, POINTL *BrushPoint)
if (ClipRegion->iDComplexity == DC_RECT)
{
- FillSolidUnlocked(pso, &(ClipRegion->rclBounds), iColor);
+ FillSolid(pso, &(ClipRegion->rclBounds), iColor);
} else {
/* Enumerate all the rectangles and draw them */
do {
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++) {
- FillSolidUnlocked(pso, RectEnum.arcl + i, iColor);
+ FillSolid(pso, RectEnum.arcl + i, iColor);
}
} while (EnumMore);
}
DPRINT("pso->iType == %d\n", pso->iType);
/* Is the surface's Paint function hooked? */
- if((pso->iType!=STYPE_BITMAP) && (psurf->flHooks & HOOK_PAINT))
+ if((pso->iType!=STYPE_BITMAP) && (psurf->flags & HOOK_PAINT))
{
// Call the driver's DrvPaint
- SURFACE_LockBitmapBits(psurf);
- MouseSafetyOnDrawStart(pso, ClipRegion->rclBounds.left,
- ClipRegion->rclBounds.top, ClipRegion->rclBounds.right,
- ClipRegion->rclBounds.bottom);
-
ret = GDIDEVFUNCS(pso).Paint(
pso, ClipRegion, Brush, BrushOrigin, Mix);
- MouseSafetyOnDrawEnd(pso);
- SURFACE_UnlockBitmapBits(psurf);
return ret;
}
return EngPaint(pso, ClipRegion, Brush, BrushOrigin, Mix );
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Support for physical devices
+ * FILE: subsystems/win32/win32k/eng/pdevobj.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+#include <win32k.h>
+
+#include <intrin.h>
+
+#define NDEBUG
+#include <debug.h>
+
+PPDEVOBJ gppdevPrimary = NULL;
+
+static PPDEVOBJ gppdevList = NULL;
+static HSEMAPHORE ghsemPDEV;
+
+BOOL
+NTAPI
+InitPDEVImpl()
+{
+ ghsemPDEV = EngCreateSemaphore();
+ return TRUE;
+}
+
+
+PPDEVOBJ
+PDEVOBJ_AllocPDEV()
+{
+ PPDEVOBJ ppdev;
+
+ ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV);
+ if (!ppdev)
+ return NULL;
+
+ RtlZeroMemory(ppdev, sizeof(PDEVOBJ));
+
+ ppdev->cPdevRefs = 1;
+
+ return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev)
+{
+ /* Lock loader */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* Decrease reference count */
+ --ppdev->cPdevRefs;
+
+ ASSERT(ppdev->cPdevRefs >= 0) ;
+
+ /* Check if references are left */
+ if (ppdev->cPdevRefs == 0)
+ {
+ /* Do we have a surface? */
+ if(ppdev->pSurface)
+ {
+ /* Release the surface and let the driver free it */
+ SURFACE_ShareUnlockSurface(ppdev->pSurface);
+ ppdev->pfn.DisableSurface(ppdev->dhpdev);
+ }
+
+ /* Do we have a palette? */
+ if(ppdev->ppalSurf)
+ {
+ PALETTE_ShareUnlockPalette(ppdev->ppalSurf);
+ }
+
+ /* Disable PDEV */
+ ppdev->pfn.DisablePDEV(ppdev->dhpdev);
+
+ /* Remove it from list */
+ if( ppdev == gppdevList )
+ gppdevList = ppdev->ppdevNext ;
+ else
+ {
+ PPDEVOBJ ppdevCurrent = gppdevList;
+ BOOL found = FALSE ;
+ while (!found && ppdevCurrent->ppdevNext)
+ {
+ if (ppdevCurrent->ppdevNext == ppdev)
+ found = TRUE;
+ else
+ ppdevCurrent = ppdevCurrent->ppdevNext ;
+ }
+ if(found)
+ ppdevCurrent->ppdevNext = ppdev->ppdevNext;
+ }
+
+ /* Is this the primary one ? */
+ if (ppdev == gppdevPrimary)
+ gppdevPrimary = NULL;
+
+ /* Free it */
+ ExFreePoolWithTag(ppdev, GDITAG_PDEV );
+ }
+
+ /* Unlock loader */
+ EngReleaseSemaphore(ghsemPDEV);
+
+}
+
+BOOL
+NTAPI
+PDEVOBJ_bEnablePDEV(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdevmode,
+ PWSTR pwszLogAddress)
+{
+ PFN_DrvEnablePDEV pfnEnablePDEV;
+
+ DPRINT1("PDEVOBJ_bEnablePDEV()\n");
+
+ /* Get the DrvEnablePDEV function */
+ pfnEnablePDEV = ppdev->pldev->pfn.EnablePDEV;
+
+ /* Call the drivers DrvEnablePDEV function */
+ ppdev->dhpdev = pfnEnablePDEV(pdevmode,
+ pwszLogAddress,
+ HS_DDI_MAX,
+ ppdev->ahsurf,
+ sizeof(GDIINFO),
+ &ppdev->gdiinfo,
+ sizeof(DEVINFO),
+ &ppdev->devinfo,
+ (HDEV)ppdev,
+ ppdev->pGraphicsDevice->pwszDescription,
+ ppdev->pGraphicsDevice->DeviceObject);
+
+ /* Fix up some values */
+ if (ppdev->gdiinfo.ulLogPixelsX == 0)
+ ppdev->gdiinfo.ulLogPixelsX = 96;
+
+ if (ppdev->gdiinfo.ulLogPixelsY == 0)
+ ppdev->gdiinfo.ulLogPixelsY = 96;
+
+ /* Setup Palette */
+ GDIOBJ_SetOwnership(ppdev->devinfo.hpalDefault, NULL);
+ ppdev->ppalSurf = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
+
+ DPRINT1("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
+
+ return TRUE;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vCompletePDEV(
+ PPDEVOBJ ppdev)
+{
+ /* Call the drivers DrvCompletePDEV function */
+ ppdev->pldev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+}
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+ PPDEVOBJ ppdev)
+{
+ HSURF hsurf;
+
+ /* Check if we already have a surface */
+ if (ppdev->pSurface)
+ {
+ /* Increment reference count */
+ GDIOBJ_IncrementShareCount(&ppdev->pSurface->BaseObject);
+ }
+ else
+ {
+ /* Call the drivers DrvEnableSurface */
+ hsurf = ppdev->pldev->pfn.EnableSurface(ppdev->dhpdev);
+
+ /* Lock the surface */
+ ppdev->pSurface = SURFACE_ShareLockSurface(hsurf);
+ }
+
+ DPRINT("PDEVOBJ_pSurface() returning %p\n", ppdev->pSurface);
+ return ppdev->pSurface;
+}
+
+PDEVMODEW
+NTAPI
+PDEVOBJ_pdmMatchDevMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVMODEW pdmCurrent;
+ INT i;
+ DWORD dwFields;
+
+ pGraphicsDevice = ppdev->pGraphicsDevice;
+
+ for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+ {
+ pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
+
+ /* Compare asked DEVMODE fields
+ * Only compare those that are valid in both DEVMODE structs */
+ dwFields = pdmCurrent->dmFields & pdm->dmFields ;
+ /* For now, we only need those */
+ if ((dwFields & DM_BITSPERPEL) &&
+ (pdmCurrent->dmBitsPerPel != pdm->dmBitsPerPel))
+ continue;
+ if ((dwFields & DM_PELSWIDTH) &&
+ (pdmCurrent->dmPelsWidth != pdm->dmPelsWidth))
+ continue;
+ if ((dwFields & DM_PELSHEIGHT) &&
+ (pdmCurrent->dmPelsHeight != pdm->dmPelsHeight))
+ continue;
+ if ((dwFields & DM_DISPLAYFREQUENCY) &&
+ (pdmCurrent->dmDisplayFrequency != pdm->dmDisplayFrequency))
+ continue;
+
+ /* Match! Return the DEVMODE */
+ return pdmCurrent;
+ }
+
+ /* Nothing found */
+ return NULL;
+}
+
+static
+PPDEVOBJ
+EngpCreatePDEV(
+ PUNICODE_STRING pustrDeviceName,
+ PDEVMODEW pdm)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PPDEVOBJ ppdev;
+
+ /* Try to find the GRAPHICS_DEVICE */
+ if (pustrDeviceName)
+ {
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0, 0);
+ if (!pGraphicsDevice)
+ {
+ DPRINT1("No GRAPHICS_DEVICE found for %ls!\n",
+ pustrDeviceName ? pustrDeviceName->Buffer : 0);
+ return NULL;
+ }
+ }
+ else
+ {
+ pGraphicsDevice = gpPrimaryGraphicsDevice;
+ }
+
+ /* Allocate a new PDEVOBJ */
+ ppdev = PDEVOBJ_AllocPDEV();
+ if (!ppdev)
+ {
+ DPRINT1("failed to allocate a PDEV\n");
+ return NULL;
+ }
+
+ /* If no DEVMODEW is given, ... */
+ if (!pdm)
+ {
+ /* ... use the device's default one */
+ pdm = pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
+ DPRINT1("Using iDefaultMode = %ld\n", pGraphicsDevice->iDefaultMode);
+ }
+
+ /* Try to get a diplay driver */
+ ppdev->pldev = EngLoadImageEx(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
+ if (!ppdev->pldev)
+ {
+ DPRINT1("Could not load display driver '%ls'\n",
+ pGraphicsDevice->pDiplayDrivers);
+ ExFreePoolWithTag(ppdev, GDITAG_PDEV);
+ return NULL;
+ }
+
+ /* Copy the function table */
+ ppdev->pfn = ppdev->pldev->pfn;
+
+ /* Set MovePointer function */
+ ppdev->pfnMovePointer = ppdev->pfn.MovePointer;
+ if (!ppdev->pfnMovePointer)
+ ppdev->pfnMovePointer = EngMovePointer;
+
+ ppdev->pGraphicsDevice = pGraphicsDevice;
+ ppdev->hsemDevLock = EngCreateSemaphore();
+ // Should we change the ative mode of pGraphicsDevice ?
+ ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm) ;
+
+ /* FIXME! */
+ ppdev->flFlags = PDEV_DISPLAY;
+
+ /* HACK: Don't use the pointer */
+ ppdev->Pointer.Exclude.right = -1;
+
+ /* Call the driver to enable the PDEV */
+ if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL))
+ {
+ DPRINT1("Failed to enable PDEV!\n");
+ ASSERT(FALSE);
+ }
+
+ /* FIXME: this must be done in a better way */
+ pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
+
+ /* Tell the driver that the PDEV is ready */
+ PDEVOBJ_vCompletePDEV(ppdev);
+
+ /* Return the PDEV */
+ return ppdev;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vSwitchPdev(
+ PPDEVOBJ ppdev,
+ PPDEVOBJ ppdev2)
+{
+ PDEVOBJ pdevTmp;
+ DWORD tmpStateFlags;
+
+ /* Exchange data */
+ pdevTmp = *ppdev;
+
+ /* Exchange driver functions */
+ ppdev->pfn = ppdev2->pfn;
+ ppdev2->pfn = pdevTmp.pfn;
+
+ /* Exchange LDEVs */
+ ppdev->pldev = ppdev2->pldev;
+ ppdev2->pldev = pdevTmp.pldev;
+
+ /* Exchange DHPDEV */
+ ppdev->dhpdev = ppdev2->dhpdev;
+ ppdev2->dhpdev = pdevTmp.dhpdev;
+
+ /* Exchange surfaces and associate them with their new PDEV */
+ ppdev->pSurface = ppdev2->pSurface;
+ ppdev2->pSurface = pdevTmp.pSurface;
+ ppdev->pSurface->SurfObj.hdev = (HDEV)ppdev;
+ ppdev2->pSurface->SurfObj.hdev = (HDEV)ppdev2;
+
+ /* Exchange devinfo */
+ ppdev->devinfo = ppdev2->devinfo;
+ ppdev2->devinfo = pdevTmp.devinfo;
+
+ /* Exchange gdiinfo */
+ ppdev->gdiinfo = ppdev2->gdiinfo;
+ ppdev2->gdiinfo = pdevTmp.gdiinfo;
+
+ /* Exchange DEVMODE */
+ ppdev->pdmwDev = ppdev2->pdmwDev;
+ ppdev2->pdmwDev = pdevTmp.pdmwDev;
+
+ /* Exchange state flags */
+ tmpStateFlags = ppdev->pGraphicsDevice->StateFlags;
+ ppdev->pGraphicsDevice->StateFlags = ppdev2->pGraphicsDevice->StateFlags;
+ ppdev2->pGraphicsDevice->StateFlags = tmpStateFlags;
+
+ /* Notify each driver instance of its new HDEV association */
+ ppdev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev);
+ ppdev2->pfn.CompletePDEV(ppdev2->dhpdev, (HDEV)ppdev2);
+}
+
+
+BOOL
+NTAPI
+PDEVOBJ_bSwitchMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm)
+{
+ UNICODE_STRING ustrDevice;
+ PPDEVOBJ ppdevTmp;
+ PSURFACE pSurface;
+ BOOL retval = FALSE;
+
+ /* Lock the PDEV */
+ EngAcquireSemaphore(ppdev->hsemDevLock);
+ /* And everything else */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+
+ // Lookup the GraphicsDevice + select DEVMODE
+ // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
+
+ /* 1. Temporarily disable the current PDEV */
+ if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE))
+ {
+ DPRINT1("DrvAssertMode failed\n");
+ goto leave;
+ }
+
+ /* 2. Create new PDEV */
+ RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName);
+ ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm);
+ if (!ppdevTmp)
+ {
+ DPRINT1("Failed to create a new PDEV\n");
+ goto leave;
+ }
+
+ /* 3. Create a new surface */
+ pSurface = PDEVOBJ_pSurface(ppdevTmp);
+ if (!pSurface)
+ {
+ DPRINT1("DrvEnableSurface failed\n");
+ goto leave;
+ }
+
+ /* 4. Get DirectDraw information */
+ /* 5. Enable DirectDraw Not traced */
+ /* 6. Copy old PDEV state to new PDEV instance */
+
+ /* 7. Switch the PDEVs */
+ PDEVOBJ_vSwitchPdev(ppdev, ppdevTmp);
+
+ /* 8. Disable DirectDraw */
+
+ PDEVOBJ_vRelease(ppdevTmp);
+
+ /* Update primary display capabilities */
+ if(ppdev == gppdevPrimary)
+ {
+ PDEVOBJ_vGetDeviceCaps(ppdev, &GdiHandleTable->DevCaps);
+ }
+
+ /* Success! */
+ retval = TRUE;
+leave:
+ /* Unlock PDEV */
+ EngReleaseSemaphore(ppdev->hsemDevLock);
+ EngReleaseSemaphore(ghsemPDEV);
+
+ DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface);
+
+ return retval;
+}
+
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(
+ PUNICODE_STRING pustrDeviceName)
+{
+ UNICODE_STRING ustrCurrent;
+ PPDEVOBJ ppdev;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+
+ /* Acquire PDEV lock */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* If no device name is given, ... */
+ if (!pustrDeviceName && gppdevPrimary)
+ {
+ /* ... use the primary PDEV */
+ ppdev = gppdevPrimary;
+
+ /* Reference the pdev */
+ InterlockedIncrement(&ppdev->cPdevRefs);
+ goto leave;
+ }
+
+ /* Loop all present PDEVs */
+ for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
+ {
+ /* Get a pointer to the GRAPHICS_DEVICE */
+ pGraphicsDevice = ppdev->pGraphicsDevice;
+
+ /* Compare the name */
+ RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
+ if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE))
+ {
+ /* Found! Reference the PDEV */
+ InterlockedIncrement(&ppdev->cPdevRefs);
+ break;
+ }
+ }
+
+ /* Did we find one? */
+ if (!ppdev)
+ {
+ /* No, create a new PDEV */
+ ppdev = EngpCreatePDEV(pustrDeviceName, NULL);
+ if (ppdev)
+ {
+ /* Insert the PDEV into the list */
+ ppdev->ppdevNext = gppdevList;
+ gppdevList = ppdev;
+
+ /* Set as primary PDEV, if we don't have one yet */
+ if (!gppdevPrimary)
+ {
+ gppdevPrimary = ppdev;
+ ppdev->pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE;
+ }
+ }
+ }
+
+leave:
+ /* Release PDEV lock */
+ EngReleaseSemaphore(ghsemPDEV);
+
+ return ppdev;
+}
+
+INT
+NTAPI
+PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev)
+{
+ INT ret = CM_NONE;
+
+ if (ppdev->flFlags & PDEV_DISPLAY)
+ {
+ if (ppdev->devinfo.iDitherFormat == BMF_8BPP ||
+ ppdev->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
+ ret = CM_GAMMA_RAMP;
+ }
+
+ if (ppdev->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
+ ret |= CM_CMYK_COLOR;
+ if (ppdev->devinfo.flGraphicsCaps & GCAPS_ICM)
+ ret |= CM_DEVICE_ICM;
+
+ return ret;
+}
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+ IN PPDEVOBJ ppdev,
+ OUT PDEVCAPS pDevCaps)
+{
+ PGDIINFO pGdiInfo = &ppdev->gdiinfo;
+
+ pDevCaps->ulVersion = pGdiInfo->ulVersion;
+ pDevCaps->ulTechnology = pGdiInfo->ulTechnology;
+ pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000;
+ pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000;
+ pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize;
+ pDevCaps->ulVertSize = pGdiInfo->ulVertSize;
+ pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes;
+ pDevCaps->ulVertRes = pGdiInfo->ulVertRes;
+ pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel;
+ if (pDevCaps->ulBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
+ pDevCaps->ulPlanes = pGdiInfo->cPlanes;
+ pDevCaps->ulNumPens = pGdiInfo->ulNumColors;
+ if (pDevCaps->ulNumPens != -1) pDevCaps->ulNumPens *= 5;
+ pDevCaps->ulNumFonts = 0; // PDEVOBJ_cFonts(ppdev);
+ pDevCaps->ulNumColors = pGdiInfo->ulNumColors;
+ pDevCaps->ulRasterCaps = pGdiInfo->flRaster;
+ pDevCaps->ulAspectX = pGdiInfo->ulAspectX;
+ pDevCaps->ulAspectY = pGdiInfo->ulAspectY;
+ pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY;
+ pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX;
+ pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY;
+ pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg;
+ pDevCaps->ulColorRes = pGdiInfo->ulDACRed +
+ pGdiInfo->ulDACGreen +
+ pGdiInfo->ulDACBlue;
+ pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx;
+ pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy;
+ pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
+ pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
+ pDevCaps->ulTextCaps = pGdiInfo->flTextCaps;
+ pDevCaps->ulTextCaps |= (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
+ if (pGdiInfo->ulTechnology != DT_PLOTTER)
+ pDevCaps->ulTextCaps |= TC_VA_ABLE;
+ pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh;
+ pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes;
+ pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes;
+ pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment;
+ pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes;
+ pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes;
+ pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
+ pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
+ pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend;
+ pDevCaps->ulColorMgmtCaps = PDEVOBJ_iGetColorManagementCaps(ppdev);
+}
+
+
+/** Exported functions ********************************************************/
+
+LPWSTR
+APIENTRY
+EngGetDriverName(IN HDEV hdev)
+{
+ PPDEVOBJ ppdev = (PPDEVOBJ)hdev;
+ PLDEVOBJ pldev;
+
+ if (!hdev)
+ return NULL;
+
+ pldev = ppdev->pldev;
+ ASSERT(pldev);
+
+ if (!pldev->pGdiDriverInfo)
+ return NULL;
+
+ return pldev->pGdiDriverInfo->DriverName.Buffer;
+}
+
+
+INT
+APIENTRY
+NtGdiGetDeviceCaps(
+ HDC hdc,
+ INT Index)
+{
+ PDC pdc;
+ DEVCAPS devcaps;
+
+ /* Lock the given DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+
+ /* Get the data */
+ PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ /* Return capability */
+ switch (Index)
+ {
+ case DRIVERVERSION:
+ return devcaps.ulVersion;
+
+ case TECHNOLOGY:
+ return devcaps.ulTechnology;
+
+ case HORZSIZE:
+ return devcaps.ulHorzSize;
+
+ case VERTSIZE:
+ return devcaps.ulVertSize;
+
+ case HORZRES:
+ return devcaps.ulHorzRes;
+
+ case VERTRES:
+ return devcaps.ulVertRes;
+
+ case LOGPIXELSX:
+ return devcaps.ulLogPixelsX;
+
+ case LOGPIXELSY:
+ return devcaps.ulLogPixelsY;
+
+ case BITSPIXEL:
+ return devcaps.ulBitsPixel;
+
+ case PLANES:
+ return devcaps.ulPlanes;
+
+ case NUMBRUSHES:
+ return -1;
+
+ case NUMPENS:
+ return devcaps.ulNumPens;
+
+ case NUMFONTS:
+ return devcaps.ulNumFonts;
+
+ case NUMCOLORS:
+ return devcaps.ulNumColors;
+
+ case ASPECTX:
+ return devcaps.ulAspectX;
+
+ case ASPECTY:
+ return devcaps.ulAspectY;
+
+ case ASPECTXY:
+ return devcaps.ulAspectXY;
+
+ case CLIPCAPS:
+ return CP_RECTANGLE;
+
+ case SIZEPALETTE:
+ return devcaps.ulSizePalette;
+
+ case NUMRESERVED:
+ return 20;
+
+ case COLORRES:
+ return devcaps.ulColorRes;
+
+ case DESKTOPVERTRES:
+ return devcaps.ulVertRes;
+
+ case DESKTOPHORZRES:
+ return devcaps.ulHorzRes;
+
+ case BLTALIGNMENT:
+ return devcaps.ulBltAlignment;
+
+ case SHADEBLENDCAPS:
+ return devcaps.ulShadeBlend;
+
+ case COLORMGMTCAPS:
+ return devcaps.ulColorMgmtCaps;
+
+ case PHYSICALWIDTH:
+ return devcaps.ulPhysicalWidth;
+
+ case PHYSICALHEIGHT:
+ return devcaps.ulPhysicalHeight;
+
+ case PHYSICALOFFSETX:
+ return devcaps.ulPhysicalOffsetX;
+
+ case PHYSICALOFFSETY:
+ return devcaps.ulPhysicalOffsetY;
+
+ case VREFRESH:
+ return devcaps.ulVRefresh;
+
+ case RASTERCAPS:
+ return devcaps.ulRasterCaps;
+
+ case CURVECAPS:
+ return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+ CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+
+ case LINECAPS:
+ return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+ LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+
+ case POLYGONALCAPS:
+ return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+ PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+
+ case TEXTCAPS:
+ return devcaps.ulTextCaps;
+
+ case CAPS1:
+ case PDEVICESIZE:
+ case SCALINGFACTORX:
+ case SCALINGFACTORY:
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+
+BOOL
+APIENTRY
+NtGdiGetDeviceCapsAll(
+ IN HDC hDC,
+ OUT PDEVCAPS pDevCaps)
+{
+ PDC pdc;
+ DEVCAPS devcaps;
+ BOOL bResult = TRUE;
+
+ /* Lock the given DC */
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ /* Get the data */
+ PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps);
+
+ /* Unlock the DC */
+ DC_UnlockDc(pdc);
+
+ /* Copy data to caller */
+ _SEH2_TRY
+ {
+ ProbeForWrite(pDevCaps, sizeof(DEVCAPS), 1);
+ RtlCopyMemory(pDevCaps, &devcaps, sizeof(DEVCAPS));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ bResult = FALSE;
+ }
+ _SEH2_END;
+
+ return bResult;
+}
+
+DHPDEV
+APIENTRY
+NtGdiGetDhpdev(
+ IN HDEV hdev)
+{
+ PPDEVOBJ ppdev;
+ DHPDEV dhpdev = NULL;
+
+ /* Check parameter */
+ if (!hdev || (PCHAR)hdev < (PCHAR)MmSystemRangeStart)
+ return NULL;
+
+ /* Lock PDEV list */
+ EngAcquireSemaphore(ghsemPDEV);
+
+ /* Walk through the list of PDEVs */
+ for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext)
+ {
+ /* Compare with the given HDEV */
+ if (ppdev == hdev)
+ {
+ /* Found the PDEV! Get it's dhpdev and break */
+ dhpdev = ppdev->dhpdev;
+ break;
+ }
+ }
+
+ /* Unlock PDEV list */
+ EngReleaseSemaphore(ghsemPDEV);
+
+ return dhpdev;
+}
+
+PSIZEL
+FASTCALL
+PDEVOBJ_sizl(PPDEVOBJ ppdev, PSIZEL psizl)
+{
+ if (ppdev->flFlags & PDEV_META_DEVICE)
+ {
+ psizl->cx = ppdev->ulHorzRes;
+ psizl->cy = ppdev->ulVertRes;
+ }
+ else
+ {
+ psizl->cx = ppdev->gdiinfo.ulHorzRes;
+ psizl->cy = ppdev->gdiinfo.ulVertRes;
+ }
+ return psizl;
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: RLE compression
+ * FILE: subsystems/win32k/eng/rlecomp.c
+ * PROGRAMER: Jason Filby
+ */
+
+#include <win32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+enum Rle_EscapeCodes
+{
+ RLE_EOL = 0, /* End of line */
+ RLE_END = 1, /* End of bitmap */
+ RLE_DELTA = 2 /* Delta */
+};
+
+VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format)
+{
+ INT x = 0;
+ INT y = Size.cy - 1;
+ INT c;
+ INT length;
+ INT width;
+ INT height = Size.cy - 1;
+ BYTE *begin = CompressedBits;
+ BYTE *bits = CompressedBits;
+ BYTE *temp;
+ INT shift = 0;
+
+ if (Format == BMF_4RLE)
+ shift = 1;
+ else if(Format != BMF_8RLE)
+ return;
+
+ width = ((Size.cx + shift) >> shift);
+
+ _SEH2_TRY
+ {
+ while (y >= 0)
+ {
+ length = (*bits++) >> shift;
+ if (length)
+ {
+ c = *bits++;
+ while (length--)
+ {
+ if (x >= width) break;
+ temp = UncompressedBits + (((height - y) * Delta) + x);
+ x++;
+ *temp = c;
+ }
+ }
+ else
+ {
+ length = *bits++;
+ switch (length)
+ {
+ case RLE_EOL:
+ x = 0;
+ y--;
+ break;
+ case RLE_END:
+ _SEH2_YIELD(return);
+ case RLE_DELTA:
+ x += (*bits++) >> shift;
+ y -= (*bits++) >> shift;
+ break;
+ default:
+ length = length >> shift;
+ while (length--)
+ {
+ c = *bits++;
+ if (x < width)
+ {
+ temp = UncompressedBits + (((height - y) * Delta) + x);
+ x++;
+ *temp = c;
+ }
+ }
+ if ((bits - begin) & 1)
+ {
+ bits++;
+ }
+ }
+ }
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Decoding error\n");
+ }
+ _SEH2_END;
+
+ return;
+}
IntGdiReleaseSemaphore ( hsem );
}
+VOID
+NTAPI
+EngAcquireSemaphoreShared(
+ IN HSEMAPHORE hsem)
+{
+ PTHREADINFO pti;
+
+ ASSERT(hsem);
+ ExEnterCriticalRegionAndAcquireResourceShared((PERESOURCE)hsem);
+ pti = PsGetThreadWin32Thread(PsGetCurrentThread());
+ if (pti) ++pti->dwEngAcquireCount;
+}
+
/*
* @implemented
*/
/* No success yet */
ret = FALSE;
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
if (UsesSource)
{
psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
- if (psoSource != psoDest)
- {
- SURFACE_LockBitmapBits(psurfSource);
- }
- MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
- InputRect.right, InputRect.bottom);
}
/* Prepare color adjustment */
/* Call the driver's DrvStretchBlt if available */
- if (psurfDest->flHooks & HOOK_STRETCHBLTROP)
+ if (psurfDest->flags & HOOK_STRETCHBLTROP)
{
/* Drv->StretchBltROP (look at http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */
ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest,
ROP);
}
- if (UsesSource)
- {
- MouseSafetyOnDrawEnd(psoSource);
- if (psoSource != psoDest)
- {
- SURFACE_UnlockBitmapBits(psurfSource);
- }
- }
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
-
return ret;
}
* PROJECT: ReactOS kernel
* PURPOSE: GDI Driver Surace Functions
* FILE: subsys/win32k/eng/surface.c
- * PROGRAMER: Jason Filby
+ * PROGRAMERS: Jason Filby
+ * Timo Kreuzer
* REVISION HISTORY:
* 3/7/1999: Created
* 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
#define NDEBUG
#include <debug.h>
-enum Rle_EscapeCodes
-{
- RLE_EOL = 0, /* End of line */
- RLE_END = 1, /* End of bitmap */
- RLE_DELTA = 2 /* Delta */
-};
+ULONG giUniqueSurface = 0;
-INT FASTCALL BitsPerFormat(ULONG Format)
+UCHAR
+gajBitsPerFormat[11] =
{
- switch (Format)
- {
- case BMF_1BPP:
- return 1;
-
- case BMF_4BPP:
- /* Fall through */
- case BMF_4RLE:
- return 4;
-
- case BMF_8BPP:
- /* Fall through */
- case BMF_8RLE:
- return 8;
-
- case BMF_16BPP:
- return 16;
-
- case BMF_24BPP:
- return 24;
+ 0, /* 0: unused */
+ 1, /* 1: BMF_1BPP */
+ 4, /* 2: BMF_4BPP */
+ 8, /* 3: BMF_8BPP */
+ 16, /* 4: BMF_16BPP */
+ 24, /* 5: BMF_24BPP */
+ 32, /* 6: BMF_32BPP */
+ 4, /* 7: BMF_4RLE */
+ 8, /* 8: BMF_8RLE */
+ 0, /* 9: BMF_JPEG */
+ 0, /* 10: BMF_PNG */
+};
- case BMF_32BPP:
- return 32;
-
- default:
- return 0;
- }
-}
ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
{
}
}
-BOOL INTERNAL_CALL
+BOOL
+INTERNAL_CALL
SURFACE_Cleanup(PVOID ObjectBody)
{
PSURFACE psurf = (PSURFACE)ObjectBody;
PVOID pvBits = psurf->SurfObj.pvBits;
+ NTSTATUS Status;
- /* If this is an API bitmap, free the bits */
- if (pvBits != NULL &&
- (psurf->flFlags & BITMAPOBJ_IS_APIBITMAP))
+ /* Check if the surface has bits */
+ if (pvBits)
{
- /* Check if we have a DIB section */
- if (psurf->hSecure)
+ /* Only bitmaps can have bits */
+ ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
+
+ /* Check if it is a DIB section */
+ if (psurf->hDIBSection)
{
- // FIXME: IMPLEMENT ME!
- // MmUnsecureVirtualMemory(psurf->hSecure);
- if (psurf->hDIBSection)
+ /* Unsecure the memory */
+ EngUnsecureMem(psurf->hSecure);
+
+ /* Calculate the real start of the section */
+ pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
+
+ /* Unmap the section */
+ Status = MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits);
+ if (!NT_SUCCESS(Status))
{
- /* DIB was created from a section */
- NTSTATUS Status;
-
- pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
- Status = ZwUnmapViewOfSection(NtCurrentProcess(), pvBits);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Could not unmap section view!\n");
- // Should we BugCheck here?
- }
+ DPRINT1("Could not unmap section view!\n");
+ // Should we BugCheck here?
+ ASSERT(FALSE);
}
- else
+ }
+ else if (psurf->SurfObj.fjBitmap & BMF_USERMEM)
+ {
+ /* Bitmap was allocated from usermode memory */
+ EngFreeUserMem(pvBits);
+ }
+ else if (psurf->SurfObj.fjBitmap & BMF_KMSECTION)
+ {
+ /* Bitmap was allocated from a kernel section */
+ if (!EngFreeSectionMem(NULL, pvBits))
{
- /* DIB was allocated */
- EngFreeUserMem(pvBits);
+ DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits);
+ // Should we BugCheck here?
+ ASSERT(FALSE);
}
}
- else
+ else if (psurf->SurfObj.fjBitmap & BMF_RLE_HACK)
{
- // FIXME: use TAG
- ExFreePool(psurf->SurfObj.pvBits);
+ /* HACK: Free RLE decompressed bits */
+ EngFreeMem(pvBits);
}
-
- if (psurf->hDIBPalette != NULL)
+ else
{
- GreDeleteObject(psurf->hDIBPalette);
+ /* There should be nothing to free */
+ ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE);
}
}
- if (NULL != psurf->BitsLock)
- {
- ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
- psurf->BitsLock = NULL;
- }
-
- return TRUE;
-}
-
-BOOL INTERNAL_CALL
-SURFACE_InitBitsLock(PSURFACE psurf)
-{
- psurf->BitsLock = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(FAST_MUTEX),
- TAG_SURFACE);
- if (NULL == psurf->BitsLock)
+ /* Free palette */
+ if(psurf->ppal)
{
- return FALSE;
+ PALETTE_ShareUnlockPalette(psurf->ppal);
}
- ExInitializeFastMutex(psurf->BitsLock);
-
return TRUE;
}
-void INTERNAL_CALL
-SURFACE_CleanupBitsLock(PSURFACE psurf)
-{
- if (NULL != psurf->BitsLock)
- {
- ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE);
- psurf->BitsLock = NULL;
- }
-}
-
-/*
- * @implemented
- */
-HBITMAP APIENTRY
-EngCreateDeviceBitmap(IN DHSURF dhsurf,
- IN SIZEL Size,
- IN ULONG Format)
+PSURFACE
+NTAPI
+SURFACE_AllocSurface(
+ IN ULONG iType,
+ IN ULONG cx,
+ IN ULONG cy,
+ IN ULONG iFormat)
{
- HBITMAP NewBitmap;
+ PSURFACE psurf;
SURFOBJ *pso;
- NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
- if (!NewBitmap)
- {
- DPRINT1("EngCreateBitmap failed\n");
- return 0;
- }
-
- pso = EngLockSurface((HSURF)NewBitmap);
- if (!pso)
+ /* Verify format */
+ if (iFormat < BMF_1BPP || iFormat > BMF_PNG)
{
- DPRINT1("EngLockSurface failed on newly created bitmap!\n");
- GreDeleteObject(NewBitmap);
+ DPRINT1("Invalid bitmap format: %ld\n", iFormat);
return NULL;
}
- pso->dhsurf = dhsurf;
- EngUnlockSurface(pso);
-
- return NewBitmap;
-}
+ /* Allocate a SURFACE object */
+ psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP);
-BOOL DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format)
-{
- INT x = 0;
- INT y = Size.cy - 1;
- INT c;
- INT length;
- INT width;
- INT height = Size.cy - 1;
- BYTE *begin = CompressedBits;
- BYTE *bits = CompressedBits;
- BYTE *temp;
- INT shift = 0;
-
- if (Format == BMF_4RLE)
- shift = 1;
- else if(Format != BMF_8RLE)
- return FALSE;
-
- width = ((Size.cx + shift) >> shift);
-
- _SEH2_TRY
- {
- while (y >= 0)
- {
- length = (*bits++) >> shift;
- if (length)
- {
- c = *bits++;
- while (length--)
- {
- if (x >= width) break;
- temp = UncompressedBits + (((height - y) * Delta) + x);
- x++;
- *temp = c;
- }
- }
- else
- {
- length = *bits++;
- switch (length)
- {
- case RLE_EOL:
- x = 0;
- y--;
- break;
- case RLE_END:
- _SEH2_YIELD(return TRUE);
- case RLE_DELTA:
- x += (*bits++) >> shift;
- y -= (*bits++) >> shift;
- break;
- default:
- length = length >> shift;
- while (length--)
- {
- c = *bits++;
- if (x < width)
- {
- temp = UncompressedBits + (((height - y) * Delta) + x);
- x++;
- *temp = c;
- }
- }
- if ((bits - begin) & 1)
- {
- bits++;
- }
- }
- }
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ if (psurf)
{
- DPRINT1("Decoding error\n");
- _SEH2_YIELD(return FALSE);
+ /* Initialize the basic fields */
+ pso = &psurf->SurfObj;
+ pso->hsurf = psurf->BaseObject.hHmgr;
+ pso->sizlBitmap.cx = cx;
+ pso->sizlBitmap.cy = cy;
+ pso->iBitmapFormat = iFormat;
+ pso->iType = iType;
+ pso->iUniq = InterlockedIncrement((PLONG)&giUniqueSurface);
+
+ /* Assign a default palette and increment its reference count */
+ psurf->ppal = appalSurfaceDefault[iFormat];
+ GDIOBJ_IncrementShareCount(&psurf->ppal->BaseObject);
}
- _SEH2_END;
- return TRUE;
+ return psurf;
}
-HBITMAP FASTCALL
-IntCreateBitmap(IN SIZEL Size,
- IN LONG Width,
- IN ULONG Format,
- IN ULONG Flags,
- IN PVOID Bits)
+BOOL
+NTAPI
+SURFACE_bSetBitmapBits(
+ IN PSURFACE psurf,
+ IN USHORT fjBitmap,
+ IN ULONG ulWidth,
+ IN PVOID pvBits OPTIONAL)
{
- HBITMAP hbmp;
- SURFOBJ *pso;
- PSURFACE psurf;
- PVOID UncompressedBits;
- ULONG UncompressedFormat;
+ SURFOBJ *pso = &psurf->SurfObj;
+ PVOID pvSection;
+ UCHAR cBitsPixel;
- if (Format == 0)
- return 0;
+ /* Only bitmaps can have bits */
+ ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
- psurf = SURFACE_AllocSurfaceWithHandle();
- if (psurf == NULL)
- {
- return 0;
- }
- hbmp = psurf->BaseObject.hHmgr;
+ /* Get bits per pixel from the format */
+ cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat];
- if (! SURFACE_InitBitsLock(psurf))
+ /* Is a width in bytes given? */
+ if (ulWidth)
{
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(hbmp);
- return 0;
+ /* Align the width (Windows compatibility, drivers expect that) */
+ ulWidth = WIDTH_BYTES_ALIGN32((ulWidth << 3) / cBitsPixel, cBitsPixel);
}
- pso = &psurf->SurfObj;
+ else
+ {
+ /* Calculate width from the bitmap width in pixels */
+ ulWidth = WIDTH_BYTES_ALIGN32(pso->sizlBitmap.cx, cBitsPixel);
+ }
- if (Format == BMF_4RLE)
- {
- pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
- pso->cjBits = pso->lDelta * Size.cy;
- UncompressedFormat = BMF_4BPP;
- UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
- DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
- }
- else if (Format == BMF_8RLE)
- {
- pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
- pso->cjBits = pso->lDelta * Size.cy;
- UncompressedFormat = BMF_8BPP;
- UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
- DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
- }
- else
- {
- pso->lDelta = abs(Width);
- pso->cjBits = pso->lDelta * Size.cy;
- UncompressedBits = Bits;
- UncompressedFormat = Format;
- }
+ /* Calculate the bitmap size in bytes */
+ pso->cjBits = ulWidth * pso->sizlBitmap.cy;
- if (UncompressedBits != NULL)
+ /* Did the caller provide bits? */
+ if (pvBits)
{
- pso->pvBits = UncompressedBits;
+ /* Yes, so let him free it */
+ fjBitmap |= BMF_DONT_FREE;
}
- else
+ else if (pso->cjBits)
{
- if (pso->cjBits == 0)
+ /* We must allocate memory, check what kind */
+ if (fjBitmap & BMF_USERMEM)
{
- pso->pvBits = NULL;
+ /* User mode memory was requested */
+ pvBits = EngAllocUserMem(pso->cjBits, 0);
}
else
{
- if (0 != (Flags & BMF_USERMEM))
- {
- pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
- }
- else
- {
- pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ?
- 0 : FL_ZERO_MEMORY,
- pso->cjBits, TAG_DIB);
- }
- if (pso->pvBits == NULL)
- {
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(hbmp);
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return 0;
- }
+ /* Use a kernel mode section */
+ fjBitmap |= BMF_KMSECTION;
+ pvBits = EngAllocSectionMem(&pvSection,
+ (fjBitmap & BMF_NOZEROINIT) ?
+ 0 : FL_ZERO_MEMORY,
+ pso->cjBits, TAG_DIB);
+
+ /* Free the section already, but keep the mapping */
+ if (pvBits) EngFreeSectionMem(pvSection, NULL);
}
+
+ /* Check for failure */
+ if (!pvBits) return FALSE;
}
- if (0 == (Flags & BMF_TOPDOWN))
+ /* Set pvBits, pvScan0 and lDelta */
+ pso->pvBits = pvBits;
+ if (fjBitmap & BMF_TOPDOWN)
{
- pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
- pso->lDelta = - pso->lDelta;
+ /* Topdown is the normal way */
+ pso->pvScan0 = pso->pvBits;
+ pso->lDelta = ulWidth;
}
else
{
- pso->pvScan0 = pso->pvBits;
+ /* Inversed bitmap (bottom up) */
+ pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth);
+ pso->lDelta = -ulWidth;
}
- pso->dhsurf = 0; /* device managed surface */
- pso->hsurf = (HSURF)hbmp;
- pso->dhpdev = NULL;
- pso->hdev = NULL;
- pso->sizlBitmap = Size;
- pso->iBitmapFormat = UncompressedFormat;
- pso->iType = STYPE_BITMAP;
- pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
- pso->iUniq = 0;
-
- psurf->flHooks = 0;
- psurf->flFlags = 0;
- psurf->dimension.cx = 0;
- psurf->dimension.cy = 0;
-
- psurf->hSecure = NULL;
- psurf->hDIBSection = NULL;
-
- SURFACE_UnlockSurface(psurf);
+ pso->fjBitmap = fjBitmap;
- return hbmp;
+ /* Success */
+ return TRUE;
}
-/* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */
-typedef struct _DEVBITMAPINFO
-{
- ULONG Format;
- ULONG Width;
- ULONG Height;
- ULONG Flags;
- ULONG Size;
-} DEVBITMAPINFO, *PDEVBITMAPINFO;
-
-SURFOBJ*
-FASTCALL
-SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
- IN PVOID Bits)
+HBITMAP
+APIENTRY
+EngCreateBitmap(
+ IN SIZEL sizl,
+ IN LONG lWidth,
+ IN ULONG iFormat,
+ IN ULONG fl,
+ IN PVOID pvBits)
{
- BOOLEAN Compressed = FALSE;
- ULONG ScanLine = 0; // Compiler is dumb
- ULONG Size;
- SURFOBJ *pso;
PSURFACE psurf;
- SIZEL LocalSize;
- BOOLEAN AllocatedLocally = FALSE;
- PVOID DecompressedBits = NULL;
-
- /*
- * First, check the format so we can get the aligned scanline width.
- * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
- * since they are compressed surfaces!
- */
- switch (BitmapInfo->Format)
- {
- case BMF_1BPP:
- ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3;
- break;
-
- case BMF_4BPP:
- ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
- break;
-
- case BMF_8BPP:
- ScanLine = (BitmapInfo->Width + 3) & ~3;
- break;
-
- case BMF_16BPP:
- ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1;
- break;
-
- case BMF_24BPP:
- ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3;
- break;
-
- case BMF_32BPP:
- ScanLine = BitmapInfo->Width << 2;
- break;
-
- case BMF_8RLE:
- ScanLine = (BitmapInfo->Width + 3) & ~3;
- Compressed = TRUE;
- break;
- case BMF_4RLE:
- ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
- Compressed = TRUE;
- break;
-
- case BMF_JPEG:
- case BMF_PNG:
- ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-)
- DPRINT1("No support for JPEG and PNG formats\n");
- return NULL;
-
- default:
- DPRINT1("Invalid bitmap format\n");
- return NULL;
- }
-
- /* Save local bitmap size */
- LocalSize.cy = BitmapInfo->Height;
- LocalSize.cx = BitmapInfo->Width;
-
- /* Does the device manage its own surface? */
- if (!Bits)
- {
- /* We need to allocate bits for the caller, figure out the size */
- if (Compressed)
- {
- /* Note: we should not be seeing this scenario from ENGDDI */
- ASSERT(FALSE);
- DPRINT1("RLE compressed bitmap requested with no valid bitmap bits\n");
- return NULL;
- }
- else
- {
- /* The height times the bytes for each scanline */
- Size = BitmapInfo->Height * ScanLine;
- }
-
- if (Size)
- {
- /* Check for allocation flag */
- if (BitmapInfo->Flags & BMF_USERMEM)
- {
- /* Get the bits from user-mode memory */
- Bits = EngAllocUserMem(Size, 'mbuG');
- }
- else
- {
- /* Get kernel bits (zeroed out if requested) */
- Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY,
- Size,
- TAG_DIB);
- }
- AllocatedLocally = TRUE;
- /* Bail out if that failed */
- if (!Bits) return NULL;
- }
- }
- else
- {
- /* Should not have asked for user memory */
- ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
-
- if (Compressed)
- {
- DecompressedBits = EngAllocMem(FL_ZERO_MEMORY, BitmapInfo->Height * ScanLine, TAG_DIB);
-
- if(!DecompressedBits)
- return NULL;
-
- if(!DecompressBitmap(LocalSize, (BYTE *)Bits, (BYTE *)DecompressedBits, ScanLine, BitmapInfo->Format))
- {
- EngFreeMem(DecompressedBits);
- return NULL;
- }
-
- BitmapInfo->Format = (BitmapInfo->Format == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
- }
- }
+ HBITMAP hbmp;
- /* Allocate the actual surface object structure */
- psurf = SURFACE_AllocSurfaceWithHandle();
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat);
if (!psurf)
{
- if(Bits && AllocatedLocally)
- {
- if(BitmapInfo->Flags & BMF_USERMEM)
- EngFreeUserMem(Bits);
- else
- EngFreeMem(Bits);
- }
- if (DecompressedBits)
- EngFreeMem(DecompressedBits);
+ DPRINT1("SURFACE_AllocSurface failed.\n");
return NULL;
}
- /* Lock down the surface */
- if (!SURFACE_InitBitsLock(psurf))
+ /* Get the handle for the bitmap */
+ hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+
+ /* Set the bitmap bits */
+ if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits))
{
/* Bail out if that failed */
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(psurf->BaseObject.hHmgr);
+ DPRINT1("SURFACE_bSetBitmapBits failed.\n");
+ SURFACE_FreeSurfaceByHandle(hbmp);
return NULL;
}
- /* We should now have our surface object */
- pso = &psurf->SurfObj;
+ /* Set public ownership */
+ GDIOBJ_SetOwnership(hbmp, NULL);
- /* Save format and flags */
- pso->iBitmapFormat = BitmapInfo->Format;
- pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM);
-
- /* Save size and type */
- pso->sizlBitmap = LocalSize;
- pso->iType = STYPE_BITMAP;
-
- /* Device-managed surface, no flags or dimension */
- pso->dhsurf = 0;
- pso->dhpdev = NULL;
- pso->hdev = NULL;
- psurf->flFlags = 0;
- psurf->dimension.cx = 0;
- psurf->dimension.cy = 0;
- psurf->hSecure = NULL;
- psurf->hDIBSection = NULL;
- psurf->flHooks = 0;
-
- /* Set bits */
- if(Compressed)
- pso->pvBits = DecompressedBits;
- else
- pso->pvBits = Bits;
-
- /* Number of bits is based on the height times the scanline */
- pso->cjBits = BitmapInfo->Height * ScanLine;
- if (BitmapInfo->Flags & BMF_TOPDOWN)
- {
- /* For topdown, the base address starts with the bits */
- pso->pvScan0 = pso->pvBits;
- pso->lDelta = ScanLine;
- }
- else
- {
- /* Otherwise we start with the end and go up */
- pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
- pso->lDelta = -ScanLine;
- }
-
- /* Finally set the handle and uniq */
- pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
- pso->iUniq = 0;
-
- /* Unlock and return the surface */
+ /* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
- return pso;
+ return hbmp;
}
/*
*/
HBITMAP
APIENTRY
-EngCreateBitmap(IN SIZEL Size,
- IN LONG Width,
- IN ULONG Format,
- IN ULONG Flags,
- IN PVOID Bits)
+EngCreateDeviceBitmap(
+ IN DHSURF dhsurf,
+ IN SIZEL sizl,
+ IN ULONG iFormat)
{
- SURFOBJ* Surface;
- DEVBITMAPINFO BitmapInfo;
-
- /* Capture the parameters */
- BitmapInfo.Format = Format;
- BitmapInfo.Width = Size.cx;
- BitmapInfo.Height = Size.cy;
- BitmapInfo.Flags = Flags;
-
- /*
- * If the display driver supports framebuffer access, use the scanline width
- * to determine the actual width of the bitmap, and convert it to pels instead
- * of bytes.
- */
- if ((Bits) && (Width))
+ PSURFACE psurf;
+ HBITMAP hbmp;
+
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat);
+ if (!psurf)
{
- switch (BitmapInfo.Format)
- {
- /* Do the conversion for each bit depth we support */
- case BMF_1BPP:
- BitmapInfo.Width = Width * 8;
- break;
- case BMF_4BPP:
- BitmapInfo.Width = Width * 2;
- break;
- case BMF_8BPP:
- BitmapInfo.Width = Width;
- break;
- case BMF_16BPP:
- BitmapInfo.Width = Width / 2;
- break;
- case BMF_24BPP:
- BitmapInfo.Width = Width / 3;
- break;
- case BMF_32BPP:
- BitmapInfo.Width = Width / 4;
- break;
- }
+ return 0;
}
-
- /* Now create the surface */
- Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits);
- if (!Surface) return 0;
-
- /* Set public ownership and reutrn the handle */
- GDIOBJ_SetOwnership(Surface->hsurf, NULL);
- return Surface->hsurf;
+
+ /* Set the device handle */
+ psurf->SurfObj.dhsurf = dhsurf;
+
+ /* Get the handle for the bitmap */
+ hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+
+ /* Set public ownership */
+ GDIOBJ_SetOwnership(hbmp, NULL);
+
+ /* Unlock the surface and return */
+ SURFACE_UnlockSurface(psurf);
+ return hbmp;
}
-/*
- * @unimplemented
- */
-HSURF APIENTRY
-EngCreateDeviceSurface(IN DHSURF dhsurf,
- IN SIZEL Size,
- IN ULONG Format)
+HSURF
+APIENTRY
+EngCreateDeviceSurface(
+ IN DHSURF dhsurf,
+ IN SIZEL sizl,
+ IN ULONG iFormat)
{
- HSURF hsurf;
- SURFOBJ *pso;
PSURFACE psurf;
+ HSURF hsurf;
- psurf = SURFACE_AllocSurfaceWithHandle();
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_DEVICE, sizl.cx, sizl.cy, iFormat);
if (!psurf)
{
return 0;
}
- hsurf = psurf->BaseObject.hHmgr;
- GDIOBJ_SetOwnership(hsurf, NULL);
+ /* Set the device handle */
+ psurf->SurfObj.dhsurf = dhsurf;
- if (!SURFACE_InitBitsLock(psurf))
- {
- SURFACE_UnlockSurface(psurf);
- SURFACE_FreeSurfaceByHandle(hsurf);
- return 0;
- }
- pso = &psurf->SurfObj;
+ /* Get the handle for the surface */
+ hsurf = psurf->SurfObj.hsurf;
- pso->dhsurf = dhsurf;
- pso->hsurf = hsurf;
- pso->sizlBitmap = Size;
- pso->iBitmapFormat = Format;
- pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
- pso->iType = STYPE_DEVICE;
- pso->iUniq = 0;
-
- psurf->flHooks = 0;
+ /* Set public ownership */
+ GDIOBJ_SetOwnership(hsurf, NULL);
+ /* Unlock the surface and return */
SURFACE_UnlockSurface(psurf);
-
return hsurf;
}
-/*
- * @implemented
- */
BOOL
APIENTRY
EngAssociateSurface(
pso->dhpdev = ppdev->dhpdev;
/* Hook up specified functions */
- psurf->flHooks = flHooks;
+ psurf->flags &= ~HOOK_FLAGS;
+ psurf->flags |= (flHooks & HOOK_FLAGS);
+
+ /* Get palette */
+ psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
SURFACE_UnlockSurface(psurf);
return TRUE;
}
-/*
- * @implemented
- */
-BOOL APIENTRY
+BOOL
+APIENTRY
EngModifySurface(
IN HSURF hsurf,
IN HDEV hdev,
pso->dhpdev = ppdev->dhpdev;
/* Hook up specified functions */
- psurf->flHooks = flHooks;
+ psurf->flags &= ~HOOK_FLAGS;
+ psurf->flags |= (flHooks & HOOK_FLAGS);
+
+ /* Get palette */
+ psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
SURFACE_UnlockSurface(psurf);
return TRUE;
}
-/*
- * @implemented
- */
-BOOL APIENTRY
+
+BOOL
+APIENTRY
EngDeleteSurface(IN HSURF hsurf)
{
GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
return TRUE;
}
-/*
- * @implemented
- */
-BOOL APIENTRY
-EngEraseSurface(SURFOBJ *pso,
- RECTL *Rect,
- ULONG iColor)
+BOOL
+APIENTRY
+EngEraseSurface(
+ SURFOBJ *pso,
+ RECTL *prcl,
+ ULONG iColor)
{
ASSERT(pso);
- ASSERT(Rect);
- return FillSolid(pso, Rect, iColor);
+ ASSERT(prcl);
+ return FillSolid(pso, prcl, iColor);
}
/*
}
-/*
- * @implemented
- */
-SURFOBJ * APIENTRY
+SURFOBJ *
+APIENTRY
EngLockSurface(IN HSURF hsurf)
{
SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
return NULL;
}
-
-/*
- * @implemented
- */
-VOID APIENTRY
+VOID
+APIENTRY
NtGdiEngUnlockSurface(IN SURFOBJ *pso)
{
EngUnlockSurface(pso);
}
-/*
- * @implemented
- */
-VOID APIENTRY
+VOID
+APIENTRY
EngUnlockSurface(IN SURFOBJ *pso)
{
if (pso != NULL)
}
}
-
/* EOF */
OutputRect.top = DestRect->bottom;
OutputRect.bottom = DestRect->top;
}
-
+
if(Clip)
{
if(OutputRect.left < Clip->rclBounds.left)
OutputRect = InputClippedRect;
}
- if(psoSource != psoDest)
- {
- SURFACE_LockBitmapBits(psurfSource);
- MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top,
- InputRect.right, InputRect.bottom);
- }
- SURFACE_LockBitmapBits(psurfDest);
- MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top,
- OutputRect.right, OutputRect.bottom);
-
- if(psurfDest->flHooks & HOOK_TRANSPARENTBLT)
+ if(psurfDest->flags & HOOK_TRANSPARENTBLT)
{
Ret = GDIDEVFUNCS(psoDest).TransparentBlt(
psoDest, psoSource, Clip, ColorTranslation, &OutputRect,
&OutputRect, &InputRect, iTransColor, Reserved);
}
- MouseSafetyOnDrawEnd(psoDest);
- SURFACE_UnlockBitmapBits(psurfDest);
- if(psoSource != psoDest)
- {
- MouseSafetyOnDrawEnd(psoSource);
- SURFACE_UnlockBitmapBits(psurfSource);
- }
-
return Ret;
}
{
ULONG iNewColor;
- /* Copy green and alpha */
+ /* Copy green */
iNewColor = iColor & 0xff00ff00;
/* Mask red and blue */
EXLATEOBJ_vInitTrivial(pexlo);
if (ppalDst == ppalSrc || !ppalSrc || !ppalDst ||
- ((ppalDst->Mode == PAL_RGB || ppalDst->Mode == PAL_BGR) &&
- ppalDst->Mode == ppalSrc->Mode))
+ ((ppalDst->flFlags == PAL_RGB || ppalDst->flFlags == PAL_BGR) &&
+ ppalDst->flFlags == ppalSrc->flFlags))
{
return;
}
pexlo->ppalSrc = ppalSrc;
pexlo->ppalDst = ppalDst;
- pexlo->xlo.iSrcType = ppalSrc->Mode;
- pexlo->xlo.iDstType = ppalDst->Mode;
+ pexlo->xlo.iSrcType = ppalSrc->flFlags;
+ pexlo->xlo.iDstType = ppalDst->flFlags;
/* Chack if both of the pallettes are indexed */
- if (!(ppalSrc->Mode & PAL_INDEXED) || !(ppalDst->Mode & PAL_INDEXED))
+ if (!(ppalSrc->flFlags & PAL_INDEXED) || !(ppalDst->flFlags & PAL_INDEXED))
{
/* At least one palette is not indexed, calculate shifts/masks */
ULONG aulMasksSrc[3], aulMasksDst[3];
pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]);
}
- if (ppalSrc->Mode & PAL_MONOCHROME)
+ if (ppalSrc->flFlags & PAL_MONOCHROME)
{
/* This is a monochrome palette */
- if (!(ppalDst->Mode & PAL_MONOCHROME))
+ if (!(ppalDst->flFlags & PAL_MONOCHROME))
{
/* Mono to color, use the dest DC's fore and back color */
pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor);
}
}
- else if (ppalDst->Mode & PAL_MONOCHROME)
+ else if (ppalDst->flFlags & PAL_MONOCHROME)
{
pexlo->pfnXlate = EXLATEOBJ_iXlateToMono;
pexlo->xlo.flXlate |= XO_TO_MONO;
pexlo->xlo.cEntries = 1;
- if (ppalSrc->Mode & PAL_INDEXED)
+ if (ppalSrc->flFlags & PAL_INDEXED)
{
pexlo->aulXlate[0] =
PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor);
}
- else if (ppalSrc->Mode & PAL_BGR)
+ else if (ppalSrc->flFlags & PAL_BGR)
{
pexlo->aulXlate[0] = crSrcBackColor;
}
- else if (ppalSrc->Mode & PAL_RGB)
+ else if (ppalSrc->flFlags & PAL_RGB)
{
pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor),
GetGValue(crSrcBackColor),
GetRValue(crSrcBackColor));
}
- else if (ppalSrc->Mode & PAL_BITFIELDS)
+ else if (ppalSrc->flFlags & PAL_BITFIELDS)
{
PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask);
pexlo->ulRedShift = CalculateShift(0xFF, pexlo->ulRedMask);
pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor);
}
}
- else if (ppalSrc->Mode & PAL_INDEXED)
+ else if (ppalSrc->flFlags & PAL_INDEXED)
{
cEntries = ppalSrc->NumColors;
pexlo->xlo.cEntries = cEntries;
pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
{
pexlo->xlo.flXlate |= XO_TABLE;
}
}
}
- else if (ppalSrc->Mode & PAL_RGB)
+ else if (ppalSrc->flFlags & PAL_RGB)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal;
- else if (ppalDst->Mode & PAL_BGR)
+ else if (ppalDst->flFlags & PAL_BGR)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
- else if (ppalDst->Mode & PAL_RGB16_555)
+ else if (ppalDst->flFlags & PAL_RGB16_555)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555;
- else if (ppalDst->Mode & PAL_RGB16_565)
+ else if (ppalDst->flFlags & PAL_RGB16_565)
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_BGR)
+ else if (ppalSrc->flFlags & PAL_BGR)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
- else if (ppalDst->Mode & PAL_RGB)
+ else if (ppalDst->flFlags & PAL_RGB)
/* The inverse function works the same */
pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR;
- else if (ppalDst->Mode & PAL_RGB16_555)
+ else if (ppalDst->flFlags & PAL_RGB16_555)
pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555;
- else if (ppalDst->Mode & PAL_RGB16_565)
+ else if (ppalDst->flFlags & PAL_RGB16_565)
pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_RGB16_555)
+ else if (ppalSrc->flFlags & PAL_RGB16_555)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal;
- else if (ppalDst->Mode & PAL_RGB)
+ else if (ppalDst->flFlags & PAL_RGB)
pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB;
- else if (ppalDst->Mode & PAL_BGR)
+ else if (ppalDst->flFlags & PAL_BGR)
pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR;
- else if (ppalDst->Mode & PAL_RGB16_565)
+ else if (ppalDst->flFlags & PAL_RGB16_565)
pexlo->pfnXlate = EXLATEOBJ_iXlate555to565;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_RGB16_565)
+ else if (ppalSrc->flFlags & PAL_RGB16_565)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal;
- else if (ppalDst->Mode & PAL_RGB)
+ else if (ppalDst->flFlags & PAL_RGB)
pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB;
- else if (ppalDst->Mode & PAL_BGR)
+ else if (ppalDst->flFlags & PAL_BGR)
pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR;
- else if (ppalDst->Mode & PAL_RGB16_555)
+ else if (ppalDst->flFlags & PAL_RGB16_555)
pexlo->pfnXlate = EXLATEOBJ_iXlate565to555;
- else if (ppalDst->Mode & PAL_BITFIELDS)
+ else if (ppalDst->flFlags & PAL_BITFIELDS)
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
}
- else if (ppalSrc->Mode & PAL_BITFIELDS)
+ else if (ppalSrc->flFlags & PAL_BITFIELDS)
{
- if (ppalDst->Mode & PAL_INDEXED)
+ if (ppalDst->flFlags & PAL_INDEXED)
pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal;
else
pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask;
PDC pdcDst)
{
PSURFACE psurfDst, psurfSrc;
- HPALETTE hpalSrc, hpalDst;
- PPALETTE ppalSrc, ppalDst, ppalDstDc;
-
- DPRINT("Enter EXLATEOBJ_vInitXlateFromDCs\n");
-
- /* Do basic init */
- EXLATEOBJ_vInitTrivial(pexlo);
psurfDst = pdcDst->dclevel.pSurface;
psurfSrc = pdcSrc->dclevel.pSurface;
+ /* Check for trivial color translation */
if (psurfDst == psurfSrc)
{
+ EXLATEOBJ_vInitTrivial(pexlo);
return;
}
- hpalSrc = psurfSrc->hDIBPalette;
- if (!hpalSrc)
- hpalSrc = pPrimarySurface->devinfo.hpalDefault;
-
- ppalSrc = PALETTE_ShareLockPalette(hpalSrc);
- if (!ppalSrc)
- return;
-
- hpalDst = psurfDst->hDIBPalette;
- if (!hpalDst) hpalDst = pPrimarySurface->devinfo.hpalDefault;
-
- ppalDst = PALETTE_ShareLockPalette(hpalDst);
- if (!ppalDst)
- {
- PALETTE_ShareUnlockPalette(ppalSrc);
- return;
- }
-
- ppalDstDc = pdcDst->dclevel.ppal;
- ASSERT(ppalDstDc);
-
- /* KB41464 details how to convert between mono and color */
- if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP)
- {
- if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- ppalSrc,
- &gpalMono,
- pdcSrc->pdcattr->crBackgroundClr,
- pdcDst->pdcattr->crBackgroundClr,
- pdcDst->pdcattr->crForegroundClr);
- }
- }
- else if (psurfSrc->SurfObj.iBitmapFormat == BMF_1BPP && !psurfSrc->hSecure)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- &gpalMono,
- ppalDst,
- 0,
- pdcDst->pdcattr->crBackgroundClr,
- pdcDst->pdcattr->crForegroundClr);
- }
- else
- {
- EXLATEOBJ_vInitialize(pexlo, ppalSrc, ppalDst, 0, 0, 0);
- }
-
- PALETTE_ShareUnlockPalette(ppalDst);
- PALETTE_ShareUnlockPalette(ppalSrc);
-}
-
-
-VOID
-NTAPI
-EXLATEOBJ_vInitBrushXlate(
- PEXLATEOBJ pexlo,
- BRUSH *pbrush,
- SURFACE *psurfDst,
- COLORREF crForegroundClr,
- COLORREF crBackgroundClr)
-{
- HPALETTE hpalDst = NULL;
- PPALETTE ppalDst, ppalPattern;
- SURFACE *psurfPattern;
-
- ASSERT(pexlo);
- ASSERT(pbrush);
- ASSERT(psurfDst);
- ASSERT(!(pbrush->flAttrs & (GDIBRUSH_IS_SOLID | GDIBRUSH_IS_NULL)));
-
- EXLATEOBJ_vInitTrivial(pexlo);
-
- hpalDst = psurfDst->hDIBPalette;
- if (!hpalDst) hpalDst = pPrimarySurface->devinfo.hpalDefault;
- ppalDst = PALETTE_ShareLockPalette(hpalDst);
- if (!ppalDst)
- {
- DPRINT1("No ppalDst!\n");
- return;
- }
-
- psurfPattern = SURFACE_ShareLockSurface(pbrush->hbmPattern);
- if (!psurfPattern)
- {
- PALETTE_ShareUnlockPalette(ppalDst);
- return;
- }
-
-#if 0
- if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP)
- {
- if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- ppalSrc,
- &gpalMono,
- 0,
- crBackgroundClr,
- crForegroundClr);
- }
- }
- else
-#endif
- if (psurfPattern->SurfObj.iBitmapFormat == BMF_1BPP &&
- !(pbrush->flAttrs & GDIBRUSH_IS_DIB))
- {
- /* Special case: 1 bpp pattern, not a DIB brush. */
- if (psurfDst->SurfObj.iBitmapFormat != BMF_1BPP)
- {
- // HACK!! FIXME: 1bpp DDBs should have gpalMono already!
- EXLATEOBJ_vInitialize(pexlo,
- &gpalMono,
- ppalDst,
- 0,
- crBackgroundClr,
- crForegroundClr);
- }
- }
- else
- {
- /* Default: use the patterns' palette */
- ppalPattern = PALETTE_LockPalette(psurfPattern->hDIBPalette);
- if (ppalPattern)
- {
- EXLATEOBJ_vInitialize(pexlo, &gpalRGB, ppalDst, 0, 0, 0);
- PALETTE_UnlockPalette(ppalPattern);
- }
- }
-
- PALETTE_ShareUnlockPalette(ppalDst);
- SURFACE_ShareUnlockSurface(psurfPattern);
+ /* Normal initialisation. No surface means DEFAULT_BITMAP */
+ EXLATEOBJ_vInitialize(pexlo,
+ psurfSrc ? psurfSrc->ppal : &gpalMono,
+ psurfDst ? psurfDst->ppal : &gpalMono,
+ pdcSrc->pdcattr->crBackgroundClr,
+ pdcDst->pdcattr->crBackgroundClr,
+ pdcDst->pdcattr->crForegroundClr);
}
VOID
/* Verify palette type match */
if (!ppal ||
((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE)
- && !(ppal->Mode & PAL_INDEXED)) ||
+ && !(ppal->flFlags & PAL_INDEXED)) ||
((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS)
- && !(ppal->Mode & PAL_BITFIELDS)))
+ && !(ppal->flFlags & PAL_BITFIELDS)))
{
return 0;
}
}
/* Copy the values into the buffer */
- if (ppal->Mode & PAL_INDEXED)
+ if (ppal->flFlags & PAL_INDEXED)
{
cPal = min(cPal, ppal->NumColors);
for (i = 0; i < cPal; i++)
#include "surface.h"
-INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth);
-int APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth);
-INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse);
+typedef struct tagBITMAPV5INFO
+{
+ BITMAPV5HEADER bmiHeader;
+ RGBQUAD bmiColors[256];
+} BITMAPV5INFO, *PBITMAPV5INFO;
+
INT APIENTRY BITMAP_GetObject(SURFACE * bmp, INT count, LPVOID buffer);
HBITMAP FASTCALL IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format, IN ULONG Flags, IN PVOID Bits);
HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap);
UINT FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel);
-INT FASTCALL BITMAP_GetWidthBytes (INT bmWidth, INT bpp);
+
+HBITMAP
+APIENTRY
+GreCreateBitmap(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
+ IN OPTIONAL PVOID pvBits);
+
+HBITMAP
+APIENTRY
+GreCreateBitmapEx(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN ULONG cjWidthBytes,
+ IN ULONG iFormat,
+ IN USHORT fjBitmap,
+ IN ULONG cjBits,
+ IN OPTIONAL PVOID pvBits,
+ IN FLONG flags);
+
+HBITMAP
+FASTCALL
+GreCreateDIBitmapInternal(
+ IN HDC hDc,
+ IN INT cx,
+ IN INT cy,
+ IN DWORD fInit,
+ IN OPTIONAL LPBYTE pjInit,
+ IN OPTIONAL PBITMAPINFO pbmi,
+ IN DWORD iUsage,
+ IN FLONG fl,
+ IN HANDLE hcmXform);
-#pragma once
+#ifndef __WIN32K_DC_H
+#define __WIN32K_DC_H
typedef struct _DC *PDC;
/* fl */
#define DC_FL_PAL_BACK 1
+#define DC_DISPLAY 1
+#define DC_DIRECT 2
+#define DC_CANCELED 4
+#define DC_PERMANANT 0x08
+#define DC_DIRTY_RAO 0x10
+#define DC_ACCUM_WMGR 0x20
+#define DC_ACCUM_APP 0x40
+#define DC_RESET 0x80
+#define DC_SYNCHRONIZEACCESS 0x100
+#define DC_EPSPRINTINGESCAPE 0x200
+#define DC_TEMPINFODC 0x400
+#define DC_FULLSCREEN 0x800
+#define DC_IN_CLONEPDEV 0x1000
+#define DC_REDIRECTION 0x2000
+#define DC_SHAREACCESS 0x4000
+
+typedef enum
+{
+ DCTYPE_DIRECT = 0,
+ DCTYPE_MEMORY = 1,
+ DCTYPE_INFO = 2,
+} DCTYPE;
+
+
/* Type definitions ***********************************************************/
typedef struct _ROS_DC_INFO
HRGN hClipRgn; /* Clip region (may be 0) */
HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */
- CLIPOBJ *CombinedClip; /* Use XCLIPOBJ in DC. */
+ CLIPOBJ *CombinedClip;
UNICODE_STRING DriverName;
NTSTATUS FASTCALL InitDcImpl(VOID);
PPDEVOBJ FASTCALL IntEnumHDev(VOID);
-HDC FASTCALL DC_AllocDC(PUNICODE_STRING Driver);
+PDC NTAPI DC_AllocDcWithHandle();
VOID FASTCALL DC_InitDC(HDC DCToInit);
-HDC FASTCALL DC_FindOpenDC(PUNICODE_STRING Driver);
VOID FASTCALL DC_AllocateDcAttr(HDC);
VOID FASTCALL DC_FreeDcAttr(HDC);
BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody);
-BOOL FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner);
+BOOL FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner);
VOID FASTCALL DC_LockDisplay(HDC);
VOID FASTCALL DC_UnlockDisplay(HDC);
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL);
VOID FASTCALL DC_vUpdateLineBrush(PDC pdc);
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc);
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc);
+VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2);
+VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2);
+
+VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC);
BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC);
VOID FASTCALL DCU_SetDcUndeletable(HDC);
+VOID NTAPI DC_vFreeDcAttr(PDC pdc);
+VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev);
COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color);
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
BOOL FASTCALL IntGdiCleanDC(HDC hDC);
VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
-INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
BOOL FASTCALL MakeInfoDC(PDC,BOOL);
BOOL FASTCALL IntSetDefaultRegion(PDC);
-extern PPDEVOBJ pPrimarySurface;
-
VOID
FORCEINLINE
DC_vSelectSurface(PDC pdc, PSURFACE psurfNew)
pdc->dclevel.ppal = ppal;
}
-BOOL FASTCALL IntPrepareDriverIfNeeded(VOID);
-extern PDEVOBJ PrimarySurface;
+extern PBRUSH pbrDefaultBrush ;
+
+#endif /* not __WIN32K_DC_H */
--- /dev/null
+
+//#define _PDEVOBJ _PDEVOBJ2
+//#define PDEVOBJ PDEVOBJ2
+//#define PPDEVOBJ PPDEVOBJ2
+
+//typedef struct _PDEVOBJ *PPDEVOBJ;
+
+#define TAG_GDEV 'gdev'
+
+VOID
+APIENTRY
+EngFileWrite(
+ IN PFILE_OBJECT pFileObject,
+ IN PVOID lpBuffer,
+ IN SIZE_T nLength,
+ IN PSIZE_T lpBytesWritten);
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpFindGraphicsDevice(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ DWORD dwFlags);
+
+PGRAPHICS_DEVICE
+NTAPI
+EngpRegisterGraphicsDevice(
+ PUNICODE_STRING pustrDeviceName,
+ PUNICODE_STRING pustrDiplayDrivers,
+ PUNICODE_STRING pustrDescription,
+ PDEVMODEW pdmDefault);
+
+BOOL
+NTAPI
+InitDeviceImpl();
+
+BOOL
+FASTCALL
+DC_AllocDcAttr(PDC pdc);
+
+//#define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl(TAG('R', 'o', 's', 'D'), (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
+NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags);
+
+BOOL
+NTAPI
+PDEVOBJ_bSwitchMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm);
+
+PDEVMODEW
+NTAPI
+PDEVOBJ_pdmMatchDevMode(
+ PPDEVOBJ ppdev,
+ PDEVMODEW pdm);
+
+extern PGRAPHICS_DEVICE gpPrimaryGraphicsDevice;
+extern PGRAPHICS_DEVICE gpVgaGraphicsDevice;
INT FASTCALL
DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse);
HBITMAP APIENTRY
-DIB_CreateDIBSection (PDC dc, PBITMAPINFO bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
-INT APIENTRY
-DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size );
+DIB_CreateDIBSection (PDC dc, CONST BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
+int FASTCALL
+DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size );
INT APIENTRY
DIB_GetDIBImageBytes (INT width, INT height, INT depth);
-INT FASTCALL
-DIB_GetDIBWidthBytes (INT width, INT depth);
-RGBQUAD * FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi);
+HPALETTE FASTCALL
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi);
HPALETTE FASTCALL
-BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);
+BuildDIBPalette (CONST BITMAPINFO *bmi);
+
+BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage);
+VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
\ No newline at end of file
VOID FASTCALL IntGdiAcquireSemaphore ( HSEMAPHORE hsem );
VOID FASTCALL IntGdiReleaseSemaphore ( HSEMAPHORE hsem );
ULONGLONG APIENTRY EngGetTickCount(VOID);
+
+BOOL
+APIENTRY
+EngFreeSectionMem(
+ IN PVOID pvSection OPTIONAL,
+ IN PVOID pvMappedBase OPTIONAL);
+
+PVOID
+APIENTRY
+EngAllocSectionMem(
+ OUT PVOID *ppvSection,
+ IN ULONG fl,
+ IN SIZE_T cjSize,
+ IN ULONG ulTag);
+
+VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG iFormat);
BOOL INTERNAL_CALL GDIOBJ_FreeObjByHandle (HGDIOBJ hObj, DWORD ObjectType);
PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType);
PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ObjectType);
+VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj);
PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process);
MIX mix);
BOOL APIENTRY
-IntEngBitBltEx(SURFOBJ *DestObj,
+IntEngBitBlt(SURFOBJ *DestObj,
SURFOBJ *SourceObj,
SURFOBJ *Mask,
CLIPOBJ *ClipRegion,
POINTL *MaskOrigin,
BRUSHOBJ *Brush,
POINTL *BrushOrigin,
- ROP4 Rop4,
- BOOL RemoveMouse);
-#define IntEngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, \
- DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, \
- Rop4) \
- IntEngBitBltEx((DestObj), (SourceObj), (Mask), (ClipRegion), \
- (ColorTranslation), (DestRect), (SourcePoint), \
- (MaskOrigin), (Brush), (BrushOrigin), (Rop4), TRUE)
+ ROP4 Rop4);
BOOL APIENTRY
IntEngStretchBlt(SURFOBJ *DestObj,
/* Other Stuff */
-INT FASTCALL
-IntGdiGetDeviceCaps(PDC dc, INT Index);
-
INT
FASTCALL
IntGdiEscape(PDC dc,
IN OUT LPDEVMODEW pDevMode,
IN DWORD dwFlags);
-LONG
-FASTCALL
-IntChangeDisplaySettings(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- IN LPDEVMODEW pDevMode,
- IN DWORD dwflags,
- IN PVOID lParam OPTIONAL);
-
HBITMAP
FASTCALL
IntCreateCompatibleBitmap(PDC Dc,
--- /dev/null
+
+#ifdef __GNUC__
+/* Hack, for bug in ld. Will be removed soon. */
+#define __ImageBase _image_base__
+#endif
+extern IMAGE_DOS_HEADER __ImageBase;
+
+
+#define TAG_LDEV 'Gldv'
+
+#define GDI_ENGINE_VERSION DDI_DRIVER_VERSION_NT5_01
+
+typedef enum
+{
+ LDEV_DEVICE_DISPLAY = 1,
+ LDEV_DEVICE_PRINTER = 2,
+ LDEV_DEVICE_META = 3,
+ LDEV_DEVICE_MIRROR = 4,
+ LDEV_IMAGE = 5,
+ LDEV_FONT = 6,
+} LDEVTYPE;
+
+typedef struct _LDEVOBJ
+{
+ struct _LDEVOBJ *pldevNext;
+ struct _LDEVOBJ *pldevPrev;
+ SYSTEM_GDI_DRIVER_INFORMATION *pGdiDriverInfo;
+ LDEVTYPE ldevtype;
+ ULONG cRefs;
+ ULONG ulDriverVersion;
+
+ union
+ {
+ PVOID apfn[INDEX_LAST];
+ DRIVER_FUNCTIONS pfn;
+ };
+
+} LDEVOBJ, *PLDEVOBJ;
+
+extern PLDEVOBJ gpldevHead;
+extern HSEMAPHORE ghsemDriverMgmt;
+
+PLDEVOBJ
+NTAPI
+LDEVOBJ_pldevLoadImage(
+ PUNICODE_STRING pusPathName,
+ LDEVTYPE ldevtype);
+
+BOOL
+NTAPI
+LDEVOBJ_bLoadDriver(
+ IN PLDEVOBJ pldev);
+
+PVOID
+NTAPI
+LDEVOBJ_pvFindImageProcAddress(
+ IN PLDEVOBJ pldev,
+ IN LPSTR lpProcName);
+
+PDEVMODEINFO
+NTAPI
+LDEVOBJ_pdmiGetModes(
+ PLDEVOBJ pldev,
+ HANDLE hDriver);
+
+BOOL
+NTAPI
+InitLDEVImpl();
+
+PLDEVOBJ
+APIENTRY
+EngLoadImageEx(
+ LPWSTR pwszDriverName,
+ ULONG ldevtype);
+
+PLDEVOBJ
+NTAPI
+EngGetLDEV(
+ PDEVMODEW pdm);
+
+NTSTATUS
+APIENTRY
+DriverEntry (
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath);
+
PVOID APIENTRY HackSecureVirtualMemory(IN PVOID,IN SIZE_T,IN ULONG,OUT PVOID *);
VOID APIENTRY HackUnsecureVirtualMemory(IN PVOID);
+NTSTATUS
+NTAPI
+RegOpenKey(
+ LPCWSTR pwszKeyName,
+ PHKEY phkey);
+
+NTSTATUS
+NTAPI
+RegQueryValue(
+ IN HKEY hkey,
+ IN PCWSTR pwszValueName,
+ IN ULONG ulType,
+ OUT PVOID pvData,
+ IN OUT PULONG pcbValue);
+
+VOID
+NTAPI
+RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData);
+
+VOID
+NTAPI
+RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData);
+
+BOOL
+NTAPI
+RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData);
+
BOOL
NTAPI
RegReadUserSetting(
#include <include/winsta.h>
-INT INTERNAL_CALL MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2);
-INT INTERNAL_CALL MouseSafetyOnDrawEnd(SURFOBJ *SurfObj);
+INT INTERNAL_CALL MouseSafetyOnDrawStart(PPDEVOBJ ppdev, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2);
+INT INTERNAL_CALL MouseSafetyOnDrawEnd(PPDEVOBJ ppdev);
#ifndef XBUTTON1
#define XBUTTON1 (0x01)
PALOBJ PalObj;
XLATEOBJ *logicalToSystem;
HPALETTE Self;
- ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
+ FLONG flFlags; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
ULONG NumColors;
PALETTEENTRY *IndexedColors;
ULONG RedMask;
HDEV hPDev;
} PALETTE, *PPALETTE;
-extern PALETTE gpalRGB, gpalBGR, gpalMono;
-
+extern PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault;
+extern PPALETTE appalSurfaceDefault[];
HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode,
ULONG NumColors,
-#pragma once
-
-#include <drivers/directx/directxint.h>
+#ifndef __WIN32K_PDEVOBJ_H
+#define __WIN32K_PDEVOBJ_H
/* PDEVOBJ flags */
#define PDEV_DISPLAY 0x00000001 /* Display device */
RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
} GDIPOINTER, *PGDIPOINTER;
+typedef struct _DEVMODEINFO
+{
+ struct _DEVMODEINFO *pdmiNext;
+ struct _LDEVOBJ *pldev;
+ ULONG cbdevmode;
+ DEVMODEW adevmode[1];
+} DEVMODEINFO, *PDEVMODEINFO;
+
+typedef struct
+{
+ DWORD dwFlags;
+ PDEVMODEW pdm;
+
+} DEVMODEENTRY, *PDEVMODEENTRY;
+
typedef struct _GRAPHICS_DEVICE
{
WCHAR szNtDeviceName[CCHDEVICENAME/2];
DWORD hkClassDriverConfig;
DWORD StateFlags; /* See DISPLAY_DEVICE_* */
ULONG cbdevmodeInfo;
- PVOID devmodeInfo;
- DWORD cbdevmodeInfo1;
- PVOID devmodeInfo1;
- LPWSTR pwszDeviceNames;
+ PDEVMODEINFO pdevmodeInfo;
+ ULONG cDevModes;
+ PDEVMODEENTRY pDevModeList;
+ LPWSTR pDiplayDrivers;
LPWSTR pwszDescription;
DWORD dwUnknown;
PVOID pUnknown;
PFILE_OBJECT FileObject;
DWORD ProtocolType;
+ ULONG iDefaultMode;
+ ULONG iCurrentMode;
} GRAPHICS_DEVICE, *PGRAPHICS_DEVICE;
typedef struct _PDEVOBJ
BASEOBJECT BaseObject;
struct _PDEVOBJ * ppdevNext;
- INT cPdevRefs;
- INT cPdevOpenRefs;
+ LONG cPdevRefs;
+ LONG cPdevOpenRefs;
struct _PDEVOBJ * ppdevParent;
FLONG flFlags; // flags
// FLONG flAccelerated;
// PFN_DrvSetPalette pfnDrvSetPalette;
// PFN_DrvNotify pfnDrvNotify;
// ULONG TagSig;
-// PLDEVOBJ pldev;
+ struct _LDEVOBJ * pldev;
DHPDEV dhpdev; /* DHPDEV for device. */
- PVOID ppalSurf; /* PEPALOBJ/PPALETTE for this device. */
+ struct _PALETTE* ppalSurf; /* PEPALOBJ/PPALETTE for this device. */
DEVINFO devinfo;
GDIINFO gdiinfo;
- HSURF pSurface; /* SURFACE for this device., FIXME: PSURFACE */
+ PSURFACE pSurface; /* SURFACE for this device. */
// HANDLE hSpooler; /* Handle to spooler, if spooler dev driver. */
// PVOID pDesktopId;
PGRAPHICS_DEVICE pGraphicsDevice;
POINTL ptlOrigion;
- PVOID pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
+ PDEVMODEW pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */
// DWORD Unknown3;
FLONG DxDd_Flags; /* DxDD active status flags. */
// LONG devAttr;
union
{
DRIVER_FUNCTIONS DriverFunctions;
+ DRIVER_FUNCTIONS pfn;
PVOID apfn[INDEX_LAST]; // B8C 0x0598
};
/* ros specific */
ULONG DxDd_nCount;
- ULONG DisplayNumber;
- DEVMODEW DMW;
- PFILE_OBJECT VideoFileObject;
- BOOLEAN PreparedDriver;
GDIPOINTER Pointer;
/* Stuff to keep track of software cursors; win32k gdi part */
UINT SafetyRemoveLevel; /* at what level was the cursor removed?
struct _EDD_DIRECTDRAW_GLOBAL * pEDDgpl;
} PDEVOBJ, *PPDEVOBJ;
-/* PDEV and EDDX extra data container.*/
-typedef struct _PDEVEDD
-{
- PDEVOBJ pdevobj;
- EDD_DIRECTDRAW_GLOBAL EDDgpl;
-} PDEVEDD, *PPDEVEDD;
+/* Globals ********************************************************************/
+
+extern PPDEVOBJ gppdevPrimary;
+#define pPrimarySurface gppdevPrimary
+
+
+/* Function prototypes ********************************************************/
+
+PPDEVOBJ
+NTAPI
+EngpGetPDEV(PUNICODE_STRING pustrDevice);
+
+VOID
+NTAPI
+PDEVOBJ_vRelease(PPDEVOBJ ppdev);
+
+PSURFACE
+NTAPI
+PDEVOBJ_pSurface(
+ PPDEVOBJ ppdev);
+
+VOID
+NTAPI
+PDEVOBJ_vGetDeviceCaps(
+ PPDEVOBJ ppdev,
+ PDEVCAPS pDevCaps);
+
+BOOL
+NTAPI
+InitPDEVImpl();
+
+BOOL
+NTAPI
+InitLDEVImpl();
+
+BOOL
+NTAPI
+InitDeviceImpl();
-PSIZEL FASTCALL PDEV_sizl(PPDEVOBJ, PSIZEL);
+PSIZEL
+FASTCALL
+PDEVOBJ_sizl(PPDEVOBJ, PSIZEL);
-extern ULONG gdwDirectDrawContext;
+#endif /* !__WIN32K_PDEVOBJ_H */
RGNDATAHEADER rdh;
RECTL *Buffer;
-} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA;
+} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA, REGION, *PREGION;
/* Functions ******************************************************************/
/* GDI surface object */
typedef struct _SURFACE
{
- BASEOBJECT BaseObject;
-
- SURFOBJ SurfObj;
- FLONG flHooks;
- FLONG flFlags;
- struct _PALETTE *ppal;
-
- union
- {
- HANDLE hSecureUMPD; // if UMPD_SURFACE set
- HANDLE hMirrorParent;// if MIRROR_SURFACE set
- HANDLE hDDSurface; // if DIRECTDRAW_SURFACE set
- };
-
- SIZEL dimension; /* For SetBitmapDimension(), do NOT use
+ BASEOBJECT BaseObject;
+
+ SURFOBJ SurfObj;
+ //XDCOBJ * pdcoAA;
+ FLONG flags;
+ struct _PALETTE *ppal;
+ //UINT unk_050;
+
+ union
+ {
+ HANDLE hSecureUMPD; // if UMPD_SURFACE set
+ HANDLE hMirrorParent;// if MIRROR_SURFACE set
+ HANDLE hDDSurface; // if DIRECTDRAW_SURFACE set
+ };
+
+ SIZEL sizlDim; /* For SetBitmapDimension(), do NOT use
to get width/height of bitmap, use
bitmap.bmWidth/bitmap.bmHeight for
that */
-
- HDC hDC; // Doc in "Undocumented Windows", page 546, seems to be supported with XP.
- ULONG cRef; // 0x064
- HPALETTE hpalHint;
- /* For device-independent bitmaps: */
- HANDLE hDIBSection;
- HANDLE hSecure;
- DWORD dwOffset;
+ HDC hdc; // Doc in "Undocumented Windows", page 546, seems to be supported with XP.
+ ULONG cRef;
+ HPALETTE hpalHint;
+
+ /* For device-independent bitmaps: */
+ HANDLE hDIBSection;
+ HANDLE hSecure;
+ DWORD dwOffset;
+ //UINT unk_078;
/* reactos specific */
- PFAST_MUTEX BitsLock; /* You need to hold this lock before you touch
- the actual bits in the bitmap */
- HPALETTE hDIBPalette;
- DWORD dsBitfields[3]; // hack, should probably use palette instead
- DWORD biClrUsed;
- DWORD biClrImportant;
+ DWORD biClrImportant;
} SURFACE, *PSURFACE;
-#define BITMAPOBJ_IS_APIBITMAP 0x1
+// flags field:
+//#define HOOK_BITBLT 0x00000001
+//#define HOOK_STRETCHBLT 0x00000002
+//#define HOOK_PLGBLT 0x00000004
+//#define HOOK_TEXTOUT 0x00000008
+//#define HOOK_PAINT 0x00000010
+//#define HOOK_STROKEPATH 0x00000020
+//#define HOOK_FILLPATH 0x00000040
+//#define HOOK_STROKEANDFILLPATH 0x00000080
+//#define HOOK_LINETO 0x00000100
+//#define SHAREACCESS_SURFACE 0x00000200
+//#define HOOK_COPYBITS 0x00000400
+//#define REDIRECTION_SURFACE 0x00000800 // ?
+//#define HOOK_MOVEPANNING 0x00000800
+//#define HOOK_SYNCHRONIZE 0x00001000
+//#define HOOK_STRETCHBLTROP 0x00002000
+//#define HOOK_SYNCHRONIZEACCESS 0x00004000
+//#define USE_DEVLOCK_SURFACE 0x00004000
+//#define HOOK_TRANSPARENTBLT 0x00008000
+//#define HOOK_ALPHABLEND 0x00010000
+//#define HOOK_GRADIENTFILL 0x00020000
+//#if (NTDDI_VERSION < 0x06000000)
+// #define HOOK_FLAGS 0x0003B5FF
+//#else
+// #define HOOK_FLAGS 0x0003B5EF
+//#endif
+#define UMPD_SURFACE 0x00040000
+#define MIRROR_SURFACE 0x00080000
+#define DIRECTDRAW_SURFACE 0x00100000
+#define DRIVER_CREATED_SURFACE 0x00200000
+#define ENG_CREATE_DEVICE_SURFACE 0x00400000
+#define DDB_SURFACE 0x00800000
+#define LAZY_DELETE_SURFACE 0x01000000
+#define BANDING_SURFACE 0x02000000
+#define API_BITMAP 0x04000000
+#define PALETTE_SELECT_SET 0x08000000
+#define UNREADABLE_SURFACE 0x10000000
+#define DYNAMIC_MODE_PALETTE 0x20000000
+#define ABORT_SURFACE 0x40000000
+#define PDEV_SURFACE 0x80000000
+
+
+#define BMF_DONT_FREE 0x100
+#define BMF_RLE_HACK 0x200
+
/* Internal interface */
-#define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE))
#define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP))
#define SURFACE_FreeSurface(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_SURF_TYPE)
#define SURFACE_FreeSurfaceByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP)
#define SURFACE_ShareUnlockSurface(pBMObj) \
GDIOBJ_ShareUnlockObjByPtr ((POBJ)pBMObj)
-#define SURFACE_LockBitmapBits(pBMObj) ExEnterCriticalRegionAndAcquireFastMutexUnsafe((pBMObj)->BitsLock)
-#define SURFACE_UnlockBitmapBits(pBMObj) ExReleaseFastMutexUnsafeAndLeaveCriticalRegion((pBMObj)->BitsLock)
-
BOOL INTERNAL_CALL SURFACE_Cleanup(PVOID ObjectBody);
-BOOL INTERNAL_CALL SURFACE_InitBitsLock(SURFACE *pBMObj);
-void INTERNAL_CALL SURFACE_CleanupBitsLock(SURFACE *pBMObj);
+
+PSURFACE
+NTAPI
+SURFACE_AllocSurface(
+ IN ULONG iType,
+ IN ULONG cx,
+ IN ULONG cy,
+ IN ULONG iFormat);
+
+BOOL
+NTAPI
+SURFACE_bSetBitmapBits(
+ IN PSURFACE psurf,
+ IN USHORT fjBitmap,
+ IN ULONG ulWidth,
+ IN PVOID pvBits OPTIONAL);
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
-INT FASTCALL BitsPerFormat (ULONG Format);
ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression);
+extern UCHAR gajBitsPerFormat[];
+#define BitsPerFormat(Format) gajBitsPerFormat[Format]
+
+#define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
+#define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3)
+
#include <include/gdifloat.h>
#include <include/engobjects.h>
#include <include/engevent.h>
+#include <include/ldevobj.h>
+#include <include/device.h>
#include <dib/dib.h>
VOID NTAPI EXLATEOBJ_vInitialize(PEXLATEOBJ pexlo, PALETTE *ppalSrc, PALETTE *ppalDst, ULONG, ULONG, ULONG);
VOID NTAPI EXLATEOBJ_vInitXlateFromDCs(PEXLATEOBJ pexlo, PDC pdcSrc, PDC pdcDst);
-VOID NTAPI EXLATEOBJ_vInitBrushXlate(PEXLATEOBJ pexlo, BRUSH *pbrush, SURFACE *psurf, COLORREF crForegroundClr, COLORREF crBackgroundClr);
VOID NTAPI EXLATEOBJ_vInitSrcMonoXlate(PEXLATEOBJ pexlo, PPALETTE ppalDst, ULONG Color0, ULONG Color1);
VOID NTAPI EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo);
+++ /dev/null
-/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/* $Id$
- *
- */
-
-#include <win32k.h>
-
-#define NDEBUG
-#include <debug.h>
-
-
-extern LIST_ENTRY GlobalDriverListHead;
-
-
-/*
- * Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from
- * here, though.
- */
-NTSTATUS APIENTRY
-LdrGetProcedureAddress (IN PVOID BaseAddress,
- IN PANSI_STRING Name,
- IN ULONG Ordinal,
- OUT PVOID *ProcedureAddress)
-{
- PIMAGE_EXPORT_DIRECTORY ExportDir;
- PUSHORT OrdinalPtr;
- PULONG NamePtr;
- PULONG AddressPtr;
- ULONG i = 0;
-
- DPRINT("LdrGetProcedureAddress (BaseAddress %x Name %Z Ordinal %lu ProcedureAddress %x)\n",
- BaseAddress, Name, Ordinal, ProcedureAddress);
-
- /* Get the pointer to the export directory */
- ExportDir = (PIMAGE_EXPORT_DIRECTORY)
- RtlImageDirectoryEntryToData (BaseAddress,
- TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT,
- &i);
-
- DPRINT("ExportDir %x i %lu\n", ExportDir, i);
-
- if (!ExportDir || !i || !ProcedureAddress)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- AddressPtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfFunctions);
- if (Name && Name->Length)
- {
- /* by name */
- OrdinalPtr = (PUSHORT)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals);
- NamePtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNames);
- for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
- {
- if (!strcmp(Name->Buffer, (char*)((ULONG_PTR)BaseAddress + *NamePtr)))
- {
- *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]);
- return STATUS_SUCCESS;
- }
- }
- DPRINT1("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
- }
- else
- {
- /* by ordinal */
- Ordinal &= 0x0000FFFF;
- if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
- {
- *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG_PTR)AddressPtr[Ordinal - ExportDir->Base]);
- return STATUS_SUCCESS;
- }
- DPRINT1("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
- }
-
- return STATUS_PROCEDURE_NOT_FOUND;
-}
-
-PVOID APIENTRY
-EngFindImageProcAddress(IN HANDLE Module,
- IN LPSTR ProcName)
-{
- PVOID Function;
- NTSTATUS Status;
- ANSI_STRING ProcNameString;
- unsigned i;
- static struct
- {
- PCSTR ProcName;
- PVOID ProcAddress;
- }
- Win32kExports[] =
- {
- { "BRUSHOBJ_hGetColorTransform", BRUSHOBJ_hGetColorTransform },
- { "EngAlphaBlend", EngAlphaBlend },
- { "EngClearEvent", EngClearEvent },
- { "EngControlSprites", EngControlSprites },
- { "EngCreateEvent", EngCreateEvent },
- { "EngDeleteEvent", EngDeleteEvent },
- { "EngDeleteFile", EngDeleteFile },
- { "EngDeleteSafeSemaphore", EngDeleteSafeSemaphore },
- { "EngDeleteWnd", EngDeleteWnd },
- { "EngDitherColor", EngDitherColor },
- { "EngGetPrinterDriver", EngGetPrinterDriver },
- { "EngGradientFill", EngGradientFill },
- { "EngHangNotification", EngHangNotification },
- { "EngInitializeSafeSemaphore", EngInitializeSafeSemaphore },
- { "EngLockDirectDrawSurface", EngLockDirectDrawSurface },
- { "EngLpkInstalled", EngLpkInstalled },
- { "EngMapEvent", EngMapEvent },
- { "EngMapFile", EngMapFile },
- { "EngMapFontFileFD", EngMapFontFileFD },
- { "EngModifySurface", EngModifySurface },
- { "EngMovePointer", EngMovePointer },
- { "EngPlgBlt", EngPlgBlt },
- { "EngQueryDeviceAttribute", EngQueryDeviceAttribute },
- { "EngQueryPalette", EngQueryPalette },
- { "EngQuerySystemAttribute", EngQuerySystemAttribute },
- { "EngReadStateEvent", EngReadStateEvent },
- { "EngRestoreFloatingPointState", EngRestoreFloatingPointState },
- { "EngSaveFloatingPointState", EngSaveFloatingPointState },
- { "EngSetEvent", EngSetEvent },
- { "EngSetPointerShape", EngSetPointerShape },
- { "EngSetPointerTag", EngSetPointerTag },
- { "EngStretchBltROP", EngStretchBltROP },
- { "EngTransparentBlt", EngTransparentBlt },
- { "EngUnlockDirectDrawSurface", EngUnlockDirectDrawSurface },
- { "EngUnmapEvent", EngUnmapEvent },
- { "EngUnmapFile", EngUnmapFile },
- { "EngUnmapFontFileFD", EngUnmapFontFileFD },
- { "EngWaitForSingleObject", EngWaitForSingleObject },
- { "FONTOBJ_pfdg", FONTOBJ_pfdg },
- { "FONTOBJ_pjOpenTypeTablePointer", FONTOBJ_pjOpenTypeTablePointer },
- { "FONTOBJ_pQueryGlyphAttrs", FONTOBJ_pQueryGlyphAttrs },
- { "FONTOBJ_pwszFontFilePaths", FONTOBJ_pwszFontFilePaths },
- { "HeapVidMemAllocAligned", HeapVidMemAllocAligned },
- { "HT_Get8BPPMaskPalette", HT_Get8BPPMaskPalette },
- { "STROBJ_bEnumPositionsOnly", STROBJ_bEnumPositionsOnly },
- { "STROBJ_bGetAdvanceWidths", STROBJ_bGetAdvanceWidths },
- { "STROBJ_fxBreakExtra", STROBJ_fxBreakExtra },
- { "STROBJ_fxCharacterExtra", STROBJ_fxCharacterExtra },
- { "VidMemFree", VidMemFree },
- { "XLATEOBJ_hGetColorTransform", XLATEOBJ_hGetColorTransform }
- };
-
- if (NULL == Module)
- {
- DPRINT("Looking for win32k export %s\n", ProcName);
- for (i = 0; i < sizeof(Win32kExports) / sizeof(Win32kExports[0]); i++)
- {
- if (0 == strcmp(ProcName, Win32kExports[i].ProcName))
- {
- DPRINT("Found it index %u address %p\n", i, Win32kExports[i].ProcName);
- return Win32kExports[i].ProcAddress;
- }
- }
- return NULL;
- }
- RtlInitAnsiString(&ProcNameString, ProcName);
- Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress,
- &ProcNameString,
- 0,
- &Function);
- if (!NT_SUCCESS(Status))
- {
- return(NULL);
- }
- return(Function);
-}
-
-
-/*
- * @implemented
- */
-HANDLE
-APIENTRY
-EngLoadImage (LPWSTR DriverName)
-{
- SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
- PDRIVERS DriverInfo = NULL;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName);
- if( !IsListEmpty(&GlobalDriverListHead) )
- {
- PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink;
- PDRIVERS Current;
- /* probably the driver was already loaded, let's try to find it out */
- while( CurrentEntry != &GlobalDriverListHead )
- {
- Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry);
- if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) {
- DriverInfo = Current;
- break;
- }
- CurrentEntry = CurrentEntry->Flink;
- };
- }
-
- if( !DriverInfo )
- {
- /* the driver was not loaded before, so let's do that */
- Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
- if (!NT_SUCCESS(Status)) {
- DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status);
- }
- else {
- DriverInfo = ExAllocatePoolWithTag(PagedPool, sizeof(DRIVERS), TAG_DRIVER);
- DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength;
- DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length;
- DriverInfo->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool, GdiDriverInfo.DriverName.MaximumLength, TAG_DRIVER);
- RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName);
- DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer;
- DriverInfo->BaseAddress = GdiDriverInfo.ImageAddress;
- InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry);
- }
- }
-
- return DriverInfo;
-}
-
-VOID
-APIENTRY
-EngUnloadImage ( IN HANDLE hModule )
-{
- NTSTATUS Status;
- PDRIVERS DriverInfo = (PDRIVERS)hModule;
-
- DPRINT("hModule 0x%x\n", hModule);
-
- Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation,
- DriverInfo->SectionPointer, sizeof(PVOID));
-
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("ZwSetSystemInformation failed with status 0x%08X\n",
- Status);
- }
- else
- {
- ExFreePool(DriverInfo->DriverName.Buffer);
- RemoveEntryList(&DriverInfo->ListEntry);
- ExFreePool(DriverInfo);
- }
-}
-
-/* EOF */
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
PSECTION_OBJECT GdiTableSection = NULL;
-LIST_ENTRY GlobalDriverListHead;
-
HANDLE GlobalUserHeap = NULL;
PSECTION_OBJECT GlobalUserHeapSection = NULL;
return(STATUS_SUCCESS);
}
+C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE);
/*
* This definition doesn't work
return STATUS_UNSUCCESSFUL;
}
- /* Initialize a list of loaded drivers in Win32 subsystem */
- InitializeListHead(&GlobalDriverListHead);
+ if (!gpsi)
+ {
+ gpsi = UserHeapAlloc(sizeof(SERVERINFO));
+ if (gpsi)
+ {
+ RtlZeroMemory(gpsi, sizeof(SERVERINFO));
+ DPRINT("Global Server Data -> %x\n", gpsi);
+ }
+ else
+ {
+ ASSERT(FALSE);
+ }
+ }
if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
return STATUS_UNSUCCESSFUL;
}
+ /* Initialize default palettes */
+ PALETTE_Init();
+
+ /* Create stock objects, ie. precreated objects commonly
+ used by win32 applications */
+ CreateStockObjects();
+ CreateSysColorObjects();
+
+ InitXlateImpl();
+ InitPDEVImpl();
+ InitLDEVImpl();
+ InitDeviceImpl();
+
+ Status = InitDcImpl();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to initialize Device context implementation!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
Status = InitUserImpl();
if (!NT_SUCCESS(Status))
{
return(Status);
}
- Status = InitDcImpl();
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to initialize Device context implementation!\n");
- return STATUS_UNSUCCESSFUL;
- }
-
/* Initialize FreeType library */
if (! InitFontSupport())
{
return STATUS_UNSUCCESSFUL;
}
- InitXlateImpl();
-
- /* Create stock objects, ie. precreated objects commonly
- used by win32 applications */
- CreateStockObjects();
- CreateSysColorObjects();
-
gusLanguageID = IntGdiGetLanguageID();
return STATUS_SUCCESS;
_SEH2_TRY
{
- /* ProbeForRead(Source,Bytes,1); */
+ ProbeForRead(Source,Bytes,1);
RtlCopyMemory(Target,Source,Bytes);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-/*
- * ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/* $Id$
- *
- * GDI Driver support routines
- * (mostly swiped from Wine)
- *
- */
-#include <win32k.h>
-
-#define NDEBUG
-#include <debug.h>
-
-/* #define TRACE_DRV_CALLS to get a log of all calls into the display driver. */
-#undef TRACE_DRV_CALLS
-
-
-typedef struct _GRAPHICS_DRIVER
-{
- PWSTR Name;
- PFN_DrvEnableDriver EnableDriver;
- int ReferenceCount;
- struct _GRAPHICS_DRIVER *Next;
-} GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
-
-static PGRAPHICS_DRIVER DriverList;
-static PGRAPHICS_DRIVER GenericDriver = NULL;
-
-BOOL DRIVER_RegisterDriver(LPCWSTR Name, PFN_DrvEnableDriver EnableDriver)
-{
- PGRAPHICS_DRIVER Driver;
-
- DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
-
- if (GenericDriver != NULL)
- {
- return FALSE;
- }
- Driver = ExAllocatePoolWithTag(PagedPool, sizeof(*Driver), TAG_DRIVER);
- if (!Driver) return FALSE;
- Driver->ReferenceCount = 0;
- Driver->EnableDriver = EnableDriver;
- if (Name)
- {
- Driver->Name = ExAllocatePoolWithTag(PagedPool,
- (wcslen(Name) + 1) * sizeof(WCHAR),
- TAG_DRIVER);
- if (Driver->Name == NULL)
- {
- DPRINT1("Out of memory\n");
- ExFreePoolWithTag(Driver, TAG_DRIVER);
- return FALSE;
- }
-
- wcscpy(Driver->Name, Name);
- Driver->Next = DriverList;
- DriverList = Driver;
- return TRUE;
- }
-
- GenericDriver = Driver;
- return TRUE;
-}
-
-PFN_DrvEnableDriver DRIVER_FindExistingDDIDriver(LPCWSTR Name)
-{
- GRAPHICS_DRIVER *Driver = DriverList;
- while (Driver && Name)
- {
- if (!_wcsicmp(Driver->Name, Name))
- {
- return Driver->EnableDriver;
- }
- Driver = Driver->Next;
- }
-
- return NULL;
-}
-
-PFN_DrvEnableDriver DRIVER_FindDDIDriver(LPCWSTR Name)
-{
- static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
- static WCHAR DefaultExtension[] = L".DLL";
- PFN_DrvEnableDriver ExistingDriver;
- SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
- NTSTATUS Status;
- LPWSTR FullName;
- LPCWSTR p;
- BOOL PathSeparatorFound;
- BOOL DotFound;
- UINT Size;
-
- DotFound = FALSE;
- PathSeparatorFound = FALSE;
- p = Name;
- while (L'\0' != *p)
- {
- if (L'\\' == *p || L'/' == *p)
- {
- PathSeparatorFound = TRUE;
- DotFound = FALSE;
- }
- else if (L'.' == *p)
- {
- DotFound = TRUE;
- }
- p++;
- }
-
- Size = (wcslen(Name) + 1) * sizeof(WCHAR);
- if (! PathSeparatorFound)
- {
- Size += sizeof(DefaultPath) - sizeof(WCHAR);
- }
- if (! DotFound)
- {
- Size += sizeof(DefaultExtension) - sizeof(WCHAR);
- }
- FullName = ExAllocatePoolWithTag(PagedPool, Size, TAG_DRIVER);
- if (NULL == FullName)
- {
- DPRINT1("Out of memory\n");
- return NULL;
- }
- if (PathSeparatorFound)
- {
- FullName[0] = L'\0';
- }
- else
- {
- wcscpy(FullName, DefaultPath);
- }
- wcscat(FullName, Name);
- if (! DotFound)
- {
- wcscat(FullName, DefaultExtension);
- }
-
- /* First see if the driver hasn't already been loaded */
- ExistingDriver = DRIVER_FindExistingDDIDriver(FullName);
- if (ExistingDriver)
- {
- ExFreePoolWithTag(FullName, TAG_DRIVER);
- return ExistingDriver;
- }
-
- /* If not, then load it */
- RtlInitUnicodeString (&GdiDriverInfo.DriverName, FullName);
- Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
-
- if (!NT_SUCCESS(Status))
- {
- ExFreePoolWithTag(FullName, TAG_DRIVER);
- return NULL;
- }
-
- DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
- DRIVER_RegisterDriver( FullName, GdiDriverInfo.EntryPoint);
- ExFreePoolWithTag(FullName, TAG_DRIVER);
- return (PFN_DrvEnableDriver)GdiDriverInfo.EntryPoint;
-}
-
-#define BEGIN_FUNCTION_MAP() \
- ULONG i; \
- for (i = 0; i < DED->c; i++) \
- { \
- switch(DED->pdrvfn[i].iFunc) \
- {
-
-#define END_FUNCTION_MAP() \
- default: \
- DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
- break; \
- } \
- }
-
-#ifdef TRACE_DRV_CALLS
-
-typedef struct _TRACEDRVINFO
- {
- unsigned Index;
- char *Name;
- PVOID DrvRoutine;
- }
-TRACEDRVINFO, *PTRACEDRVINFO;
-
-__asm__(
-" .text\n"
-"TraceDrv:\n"
-" pushl %eax\n"
-" call _FindTraceInfo\n"
-" add $4,%esp\n"
-" pushl %eax\n"
-" pushl 4(%eax)\n"
-" call _DbgPrint\n"
-" addl $4,%esp\n"
-" popl %eax\n"
-" mov 8(%eax),%eax\n"
-" jmp *%eax\n"
-);
-
-#define TRACEDRV_ROUTINE(function) \
-unsigned TraceDrvIndex##function = INDEX_Drv##function; \
-__asm__ ( \
-" .text\n" \
-"_Trace" #function ":\n" \
-" movl _TraceDrvIndex" #function ",%eax\n" \
-" jmp TraceDrv\n" \
-); \
-extern PVOID Trace##function;
-
-TRACEDRV_ROUTINE(EnablePDEV)
-TRACEDRV_ROUTINE(CompletePDEV)
-TRACEDRV_ROUTINE(DisablePDEV)
-TRACEDRV_ROUTINE(EnableSurface)
-TRACEDRV_ROUTINE(DisableSurface)
-TRACEDRV_ROUTINE(AssertMode)
-TRACEDRV_ROUTINE(Offset)
-TRACEDRV_ROUTINE(ResetPDEV)
-TRACEDRV_ROUTINE(DisableDriver)
-TRACEDRV_ROUTINE(CreateDeviceBitmap)
-TRACEDRV_ROUTINE(DeleteDeviceBitmap)
-TRACEDRV_ROUTINE(RealizeBrush)
-TRACEDRV_ROUTINE(DitherColor)
-TRACEDRV_ROUTINE(StrokePath)
-TRACEDRV_ROUTINE(FillPath)
-TRACEDRV_ROUTINE(StrokeAndFillPath)
-TRACEDRV_ROUTINE(Paint)
-TRACEDRV_ROUTINE(BitBlt)
-TRACEDRV_ROUTINE(TransparentBlt)
-TRACEDRV_ROUTINE(CopyBits)
-TRACEDRV_ROUTINE(StretchBlt)
-TRACEDRV_ROUTINE(StretchBltROP)
-TRACEDRV_ROUTINE(SetPalette)
-TRACEDRV_ROUTINE(TextOut)
-TRACEDRV_ROUTINE(Escape)
-TRACEDRV_ROUTINE(DrawEscape)
-TRACEDRV_ROUTINE(QueryFont)
-TRACEDRV_ROUTINE(QueryFontTree)
-TRACEDRV_ROUTINE(QueryFontData)
-TRACEDRV_ROUTINE(SetPointerShape)
-TRACEDRV_ROUTINE(MovePointer)
-TRACEDRV_ROUTINE(LineTo)
-TRACEDRV_ROUTINE(SendPage)
-TRACEDRV_ROUTINE(StartPage)
-TRACEDRV_ROUTINE(EndDoc)
-TRACEDRV_ROUTINE(StartDoc)
-TRACEDRV_ROUTINE(GetGlyphMode)
-TRACEDRV_ROUTINE(Synchronize)
-TRACEDRV_ROUTINE(SaveScreenBits)
-TRACEDRV_ROUTINE(GetModes)
-TRACEDRV_ROUTINE(Free)
-TRACEDRV_ROUTINE(DestroyFont)
-TRACEDRV_ROUTINE(QueryFontCaps)
-TRACEDRV_ROUTINE(LoadFontFile)
-TRACEDRV_ROUTINE(UnloadFontFile)
-TRACEDRV_ROUTINE(FontManagement)
-TRACEDRV_ROUTINE(QueryTrueTypeTable)
-TRACEDRV_ROUTINE(QueryTrueTypeOutline)
-TRACEDRV_ROUTINE(GetTrueTypeFile)
-TRACEDRV_ROUTINE(QueryFontFile)
-TRACEDRV_ROUTINE(QueryAdvanceWidths)
-TRACEDRV_ROUTINE(SetPixelFormat)
-TRACEDRV_ROUTINE(DescribePixelFormat)
-TRACEDRV_ROUTINE(SwapBuffers)
-TRACEDRV_ROUTINE(StartBanding)
-TRACEDRV_ROUTINE(NextBand)
-TRACEDRV_ROUTINE(GetDirectDrawInfo)
-TRACEDRV_ROUTINE(EnableDirectDraw)
-TRACEDRV_ROUTINE(DisableDirectDraw)
-TRACEDRV_ROUTINE(QuerySpoolType)
-TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp)
-TRACEDRV_ROUTINE(GradientFill)
-TRACEDRV_ROUTINE(SynchronizeSurface)
-TRACEDRV_ROUTINE(AlphaBlend)
-
-#define TRACEDRVINFO_ENTRY(function) \
- { INDEX_Drv##function, "Drv" #function "\n", NULL }
-static TRACEDRVINFO TraceDrvInfo[] =
- {
- TRACEDRVINFO_ENTRY(EnablePDEV),
- TRACEDRVINFO_ENTRY(CompletePDEV),
- TRACEDRVINFO_ENTRY(DisablePDEV),
- TRACEDRVINFO_ENTRY(EnableSurface),
- TRACEDRVINFO_ENTRY(DisableSurface),
- TRACEDRVINFO_ENTRY(AssertMode),
- TRACEDRVINFO_ENTRY(Offset),
- TRACEDRVINFO_ENTRY(ResetPDEV),
- TRACEDRVINFO_ENTRY(DisableDriver),
- TRACEDRVINFO_ENTRY(CreateDeviceBitmap),
- TRACEDRVINFO_ENTRY(DeleteDeviceBitmap),
- TRACEDRVINFO_ENTRY(RealizeBrush),
- TRACEDRVINFO_ENTRY(DitherColor),
- TRACEDRVINFO_ENTRY(StrokePath),
- TRACEDRVINFO_ENTRY(FillPath),
- TRACEDRVINFO_ENTRY(StrokeAndFillPath),
- TRACEDRVINFO_ENTRY(Paint),
- TRACEDRVINFO_ENTRY(BitBlt),
- TRACEDRVINFO_ENTRY(TransparentBlt),
- TRACEDRVINFO_ENTRY(CopyBits),
- TRACEDRVINFO_ENTRY(StretchBlt),
- TRACEDRVINFO_ENTRY(StretchBltROP),
- TRACEDRVINFO_ENTRY(SetPalette),
- TRACEDRVINFO_ENTRY(TextOut),
- TRACEDRVINFO_ENTRY(Escape),
- TRACEDRVINFO_ENTRY(DrawEscape),
- TRACEDRVINFO_ENTRY(QueryFont),
- TRACEDRVINFO_ENTRY(QueryFontTree),
- TRACEDRVINFO_ENTRY(QueryFontData),
- TRACEDRVINFO_ENTRY(SetPointerShape),
- TRACEDRVINFO_ENTRY(MovePointer),
- TRACEDRVINFO_ENTRY(LineTo),
- TRACEDRVINFO_ENTRY(SendPage),
- TRACEDRVINFO_ENTRY(StartPage),
- TRACEDRVINFO_ENTRY(EndDoc),
- TRACEDRVINFO_ENTRY(StartDoc),
- TRACEDRVINFO_ENTRY(GetGlyphMode),
- TRACEDRVINFO_ENTRY(Synchronize),
- TRACEDRVINFO_ENTRY(SaveScreenBits),
- TRACEDRVINFO_ENTRY(GetModes),
- TRACEDRVINFO_ENTRY(Free),
- TRACEDRVINFO_ENTRY(DestroyFont),
- TRACEDRVINFO_ENTRY(QueryFontCaps),
- TRACEDRVINFO_ENTRY(LoadFontFile),
- TRACEDRVINFO_ENTRY(UnloadFontFile),
- TRACEDRVINFO_ENTRY(FontManagement),
- TRACEDRVINFO_ENTRY(QueryTrueTypeTable),
- TRACEDRVINFO_ENTRY(QueryTrueTypeOutline),
- TRACEDRVINFO_ENTRY(GetTrueTypeFile),
- TRACEDRVINFO_ENTRY(QueryFontFile),
- TRACEDRVINFO_ENTRY(QueryAdvanceWidths),
- TRACEDRVINFO_ENTRY(SetPixelFormat),
- TRACEDRVINFO_ENTRY(DescribePixelFormat),
- TRACEDRVINFO_ENTRY(SwapBuffers),
- TRACEDRVINFO_ENTRY(StartBanding),
- TRACEDRVINFO_ENTRY(NextBand),
- TRACEDRVINFO_ENTRY(GetDirectDrawInfo),
- TRACEDRVINFO_ENTRY(EnableDirectDraw),
- TRACEDRVINFO_ENTRY(DisableDirectDraw),
- TRACEDRVINFO_ENTRY(QuerySpoolType),
- TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp),
- TRACEDRVINFO_ENTRY(GradientFill),
- TRACEDRVINFO_ENTRY(SynchronizeSurface),
- TRACEDRVINFO_ENTRY(AlphaBlend)
- };
-
-PTRACEDRVINFO
-FindTraceInfo(unsigned Index)
-{
- unsigned i;
-
- for (i = 0; i < sizeof(TraceDrvInfo) / sizeof(TRACEDRVINFO); i++)
- {
- if (TraceDrvInfo[i].Index == Index)
- {
- return TraceDrvInfo + i;
- }
- }
-
- return NULL;
-}
-
-#define DRIVER_FUNCTION(function) \
- case INDEX_Drv##function: \
- FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \
- *(PVOID*)&DF->function = &Trace##function; \
- break
-#else
-#define DRIVER_FUNCTION(function) \
- case INDEX_Drv##function: \
- *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
- break
-#endif
-
-BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
- PDRIVER_FUNCTIONS DF)
-{
- BEGIN_FUNCTION_MAP();
- DRIVER_FUNCTION(EnablePDEV);
- DRIVER_FUNCTION(CompletePDEV);
- DRIVER_FUNCTION(DisablePDEV);
- DRIVER_FUNCTION(EnableSurface);
- DRIVER_FUNCTION(DisableSurface);
- DRIVER_FUNCTION(AssertMode);
- DRIVER_FUNCTION(Offset);
- DRIVER_FUNCTION(ResetPDEV);
- DRIVER_FUNCTION(DisableDriver);
- DRIVER_FUNCTION(Unknown1);
- DRIVER_FUNCTION(CreateDeviceBitmap);
- DRIVER_FUNCTION(DeleteDeviceBitmap);
- DRIVER_FUNCTION(RealizeBrush);
- DRIVER_FUNCTION(DitherColor);
- DRIVER_FUNCTION(StrokePath);
- DRIVER_FUNCTION(FillPath);
- DRIVER_FUNCTION(StrokeAndFillPath);
- DRIVER_FUNCTION(Paint);
- DRIVER_FUNCTION(BitBlt);
- DRIVER_FUNCTION(CopyBits);
- DRIVER_FUNCTION(StretchBlt);
- DRIVER_FUNCTION(Unknown2);
- DRIVER_FUNCTION(SetPalette);
- DRIVER_FUNCTION(TextOut);
- DRIVER_FUNCTION(Escape);
- DRIVER_FUNCTION(DrawEscape);
- DRIVER_FUNCTION(QueryFont);
- DRIVER_FUNCTION(QueryFontTree);
- DRIVER_FUNCTION(QueryFontData);
- DRIVER_FUNCTION(SetPointerShape);
- DRIVER_FUNCTION(MovePointer);
- DRIVER_FUNCTION(LineTo);
- DRIVER_FUNCTION(SendPage);
- DRIVER_FUNCTION(StartPage);
- DRIVER_FUNCTION(EndDoc);
- DRIVER_FUNCTION(StartDoc);
- DRIVER_FUNCTION(Unknown3);
- DRIVER_FUNCTION(GetGlyphMode);
- DRIVER_FUNCTION(Synchronize);
- DRIVER_FUNCTION(Unknown4);
- DRIVER_FUNCTION(SaveScreenBits);
- DRIVER_FUNCTION(GetModes);
- DRIVER_FUNCTION(Free);
- DRIVER_FUNCTION(DestroyFont);
- DRIVER_FUNCTION(QueryFontCaps);
- DRIVER_FUNCTION(LoadFontFile);
- DRIVER_FUNCTION(UnloadFontFile);
- DRIVER_FUNCTION(FontManagement);
- DRIVER_FUNCTION(QueryTrueTypeTable);
- DRIVER_FUNCTION(QueryTrueTypeOutline);
- DRIVER_FUNCTION(GetTrueTypeFile);
- DRIVER_FUNCTION(QueryFontFile);
- DRIVER_FUNCTION(QueryAdvanceWidths);
- DRIVER_FUNCTION(SetPixelFormat);
- DRIVER_FUNCTION(DescribePixelFormat);
- DRIVER_FUNCTION(SwapBuffers);
- DRIVER_FUNCTION(StartBanding);
- DRIVER_FUNCTION(NextBand);
- DRIVER_FUNCTION(GetDirectDrawInfo);
- DRIVER_FUNCTION(EnableDirectDraw);
- DRIVER_FUNCTION(DisableDirectDraw);
- DRIVER_FUNCTION(QuerySpoolType);
- DRIVER_FUNCTION(Unknown5);
- DRIVER_FUNCTION(IcmCreateColorTransform);
- DRIVER_FUNCTION(IcmDeleteColorTransform);
- DRIVER_FUNCTION(IcmCheckBitmapBits);
- DRIVER_FUNCTION(IcmSetDeviceGammaRamp);
- DRIVER_FUNCTION(GradientFill);
- DRIVER_FUNCTION(StretchBltROP);
- DRIVER_FUNCTION(PlgBlt);
- DRIVER_FUNCTION(AlphaBlend);
- DRIVER_FUNCTION(SynthesizeFont);
- DRIVER_FUNCTION(GetSynthesizedFontFiles);
- DRIVER_FUNCTION(TransparentBlt);
- DRIVER_FUNCTION(QueryPerBandInfo);
- DRIVER_FUNCTION(QueryDeviceSupport);
- DRIVER_FUNCTION(Reserved1);
- DRIVER_FUNCTION(Reserved2);
- DRIVER_FUNCTION(Reserved3);
- DRIVER_FUNCTION(Reserved4);
- DRIVER_FUNCTION(Reserved5);
- DRIVER_FUNCTION(Reserved6);
- DRIVER_FUNCTION(Reserved7);
- DRIVER_FUNCTION(Reserved8);
- DRIVER_FUNCTION(DeriveSurface);
- DRIVER_FUNCTION(QueryGlyphAttrs);
- DRIVER_FUNCTION(Notify);
- DRIVER_FUNCTION(SynchronizeSurface);
- DRIVER_FUNCTION(ResetDevice);
- DRIVER_FUNCTION(Reserved9);
- DRIVER_FUNCTION(Reserved10);
- DRIVER_FUNCTION(Reserved11);
- END_FUNCTION_MAP();
-
- return TRUE;
-}
-
-typedef LONG VP_STATUS;
-typedef VP_STATUS (APIENTRY *PMP_DRIVERENTRY)(PVOID, PVOID);
-
-PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- WCHAR DeviceNameBuffer[20];
- UNICODE_STRING DeviceName;
- IO_STATUS_BLOCK Iosb;
- HANDLE DisplayHandle;
- NTSTATUS Status;
- PFILE_OBJECT VideoFileObject;
-
- swprintf(DeviceNameBuffer, L"\\??\\DISPLAY%d", DisplayNumber + 1);
- RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &DeviceName,
- 0,
- NULL,
- NULL);
- Status = ZwOpenFile(&DisplayHandle,
- FILE_ALL_ACCESS,
- &ObjectAttributes,
- &Iosb,
- 0,
- FILE_SYNCHRONOUS_IO_ALERT);
- if (NT_SUCCESS(Status))
- {
- Status = ObReferenceObjectByHandle(DisplayHandle,
- FILE_READ_DATA | FILE_WRITE_DATA,
- IoFileObjectType,
- KernelMode,
- (PVOID *)&VideoFileObject,
- NULL);
- ZwClose(DisplayHandle);
- }
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to connect to miniport (Status %lx)\n", Status);
- DPRINT1("Perhaps the miniport wasn't loaded?\n");
- return(NULL);
- }
-
- return VideoFileObject;
-}
-
-
-BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
-{
- PGRAPHICS_DRIVER Driver = NULL;
-
- if (Name)
- {
- if (DriverList != NULL)
- {
- if (!_wcsicmp(DriverList->Name, Name))
- {
- Driver = DriverList;
- DriverList = DriverList->Next;
- }
- else
- {
- Driver = DriverList;
- while (Driver->Next && _wcsicmp(Driver->Name, Name))
- {
- Driver = Driver->Next;
- }
- }
- }
- }
- else
- {
- if (GenericDriver != NULL)
- {
- Driver = GenericDriver;
- GenericDriver = NULL;
- }
- }
-
- if (Driver != NULL)
- {
- ExFreePoolWithTag(Driver->Name, TAG_DRIVER);
- ExFreePoolWithTag(Driver, TAG_DRIVER);
-
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-INT DRIVER_ReferenceDriver (LPCWSTR Name)
-{
- GRAPHICS_DRIVER *Driver = DriverList;
-
- while (Driver && Name)
- {
- DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
- if (!_wcsicmp( Driver->Name, Name))
- {
- return ++Driver->ReferenceCount;
- }
- Driver = Driver->Next;
- }
- DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
- ASSERT( GenericDriver != 0 );
- return ++GenericDriver->ReferenceCount;
-}
-
-INT DRIVER_UnreferenceDriver (LPCWSTR Name)
-{
- GRAPHICS_DRIVER *Driver = DriverList;
-
- while (Driver && Name)
- {
- DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
- if (!_wcsicmp( Driver->Name, Name))
- {
- return --Driver->ReferenceCount;
- }
- Driver = Driver->Next;
- }
- DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
- ASSERT( GenericDriver != 0 );
- return --GenericDriver->ReferenceCount;
-}
-/* EOF */
return pvBase;
}
-typedef struct tagBITMAPV5INFO
-{
- BITMAPV5HEADER bmiHeader;
- RGBQUAD bmiColors[256];
-} BITMAPV5INFO, *PBITMAPV5INFO;
-
-// FIXME: this should go to dibobj.c
-NTSTATUS
-ProbeAndConvertBitmapInfo(
- OUT BITMAPV5HEADER *pbmhDst,
- OUT RGBQUAD *pbmiColorsDst,
- ULONG cColors,
- IN PBITMAPINFO pbmiUnsafe)
-{
- DWORD dwSize;
- RGBQUAD *pbmiColors;
- ULONG ulWidthBytes;
-
- /* Get the size and probe */
- ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
- dwSize = pbmiUnsafe->bmiHeader.biSize;
- ProbeForRead(pbmiUnsafe, dwSize, 1);
-
- /* Check the size */
- // FIXME: are intermediate sizes allowed? As what are they interpreted?
- // make sure we don't use a too big dwSize later
- if (dwSize != sizeof(BITMAPCOREHEADER) &&
- dwSize != sizeof(BITMAPINFOHEADER) &&
- dwSize != sizeof(BITMAPV4HEADER) &&
- dwSize != sizeof(BITMAPV5HEADER))
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- pbmiColors = (RGBQUAD*)((PCHAR)pbmiUnsafe + dwSize);
-
- pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
-
- if (dwSize == sizeof(BITMAPCOREHEADER))
- {
- PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
-
- /* Manually copy the fields that are present */
- pbmhDst->bV5Width = pbch->bcWidth;
- pbmhDst->bV5Height = pbch->bcHeight;
- pbmhDst->bV5Planes = pbch->bcPlanes;
- pbmhDst->bV5BitCount = pbch->bcBitCount;
-
- /* Set some default values */
- pbmhDst->bV5Compression = BI_RGB;
- pbmhDst->bV5SizeImage = 0;
- pbmhDst->bV5XPelsPerMeter = 72;
- pbmhDst->bV5YPelsPerMeter = 72;
- pbmhDst->bV5ClrUsed = 0;
- pbmhDst->bV5ClrImportant = 0;
- }
- else
- {
- /* Copy valid fields */
- memcpy(pbmhDst, pbmiUnsafe, dwSize);
-
- /* Zero out the rest of the V5 header */
- memset((char*)pbmhDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
- }
-
-
- if (dwSize < sizeof(BITMAPV4HEADER))
- {
- if (pbmhDst->bV5Compression == BI_BITFIELDS)
- {
- DWORD *pMasks = (DWORD*)pbmiColors;
- pbmhDst->bV5RedMask = pMasks[0];
- pbmhDst->bV5GreenMask = pMasks[1];
- pbmhDst->bV5BlueMask = pMasks[2];
- pbmhDst->bV5AlphaMask = 0;
- pbmhDst->bV5ClrUsed = 0;
- }
-
-// pbmhDst->bV5CSType;
-// pbmhDst->bV5Endpoints;
-// pbmhDst->bV5GammaRed;
-// pbmhDst->bV5GammaGreen;
-// pbmhDst->bV5GammaBlue;
- }
-
- if (dwSize < sizeof(BITMAPV5HEADER))
- {
-// pbmhDst->bV5Intent;
-// pbmhDst->bV5ProfileData;
-// pbmhDst->bV5ProfileSize;
-// pbmhDst->bV5Reserved;
- }
-
- ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
- pbmhDst->bV5BitCount + 31) & ~31) / 8;
-
- if (pbmhDst->bV5SizeImage == 0)
- pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
-
- if (pbmhDst->bV5ClrUsed == 0)
- pbmhDst->bV5ClrUsed = pbmhDst->bV5BitCount == 1 ? 2 :
- (pbmhDst->bV5BitCount == 4 ? 16 :
- (pbmhDst->bV5BitCount == 8 ? 256 : 0));
-
- if (pbmhDst->bV5Planes != 1)
- {
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
- pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24 &&
- pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- if ((pbmhDst->bV5BitCount == 0 &&
- pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression != BI_PNG))
- {
- DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst->bV5Compression);
- return STATUS_INVALID_PARAMETER;
- }
-
- if (pbmhDst->bV5Compression == BI_BITFIELDS &&
- pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
- {
- DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount);
- return STATUS_INVALID_PARAMETER;
- }
-
- /* Copy Colors */
- cColors = min(cColors, pbmhDst->bV5ClrUsed);
- memcpy(pbmiColorsDst, pbmiColors, cColors * sizeof(RGBQUAD));
-
- return STATUS_SUCCESS;
-}
-
-
HBITMAP
NTAPI
UserLoadImage(PCWSTR pwszName)
{
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
HANDLE hFile, hSection;
BITMAPFILEHEADER *pbmfh;
LPBITMAPINFO pbmi;
- ULONG cjInfoSize;
PVOID pvBits;
HBITMAP hbmp = 0;
- BITMAPV5INFO bmiLocal;
+
+ DPRINT("Enter UserLoadImage(%ls)\n", pwszName);
/* Open the file */
hFile = W32kOpenFile(pwszName, FILE_READ_DATA);
- if (hFile == INVALID_HANDLE_VALUE)
- return NULL;
+ if (!hFile)
+ {
+ return NULL;
+ }
/* Create a section */
hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0);
ZwClose(hFile);
if (!hSection)
- return NULL;
+ {
+ return NULL;
+ }
/* Map the section */
pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0);
ZwClose(hSection);
if (!pbmfh)
- return NULL;
-
- /* Get a pointer to the BITMAPINFO */
- pbmi = (LPBITMAPINFO)(pbmfh + 1);
-
- /* Create a normalized local BITMAPINFO */
- _SEH2_TRY
{
- Status = ProbeAndConvertBitmapInfo(&bmiLocal.bmiHeader,
- bmiLocal.bmiColors,
- 256,
- pbmi);
+ return NULL;
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
- if (NT_SUCCESS(Status))
- {
- cjInfoSize = bmiLocal.bmiHeader.bV5Size +
- bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD);
- pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize);
-
- // FIXME: use Gre... so that the BITMAPINFO doesn't get probed
- hbmp = NtGdiCreateDIBitmapInternal(NULL,
- bmiLocal.bmiHeader.bV5Width,
- bmiLocal.bmiHeader.bV5Height,
- CBM_INIT,
- pvBits,
- pbmi,
- DIB_RGB_COLORS,
- bmiLocal.bmiHeader.bV5Size,
- bmiLocal.bmiHeader.bV5SizeImage,
- 0,
- 0);
- }
+ /* Get a pointer to the BITMAPINFO */
+ pbmi = (LPBITMAPINFO)(pbmfh + 1);
+ _SEH2_TRY
+ {
+ ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1);
+ ProbeForRead(pbmfh, pbmfh->bfSize, 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Bad File?\n");
+ goto leave;
+ }
+
+ if (pbmfh->bfType == 0x4D42 /* 'BM' */)
+ {
+ /* Could be BITMAPCOREINFO */
+ BITMAPINFO* pConvertedInfo;
+ HDC hdc;
+
+ pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits);
+
+ pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS);
+ if(!pConvertedInfo)
+ {
+ DPRINT1("Unable to convert the bitmap Info\n");
+ goto leave;
+ }
+
+ hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
+
+ hbmp = GreCreateDIBitmapInternal(hdc,
+ pConvertedInfo->bmiHeader.biWidth,
+ pConvertedInfo->bmiHeader.biHeight,
+ CBM_INIT,
+ pvBits,
+ pConvertedInfo,
+ DIB_RGB_COLORS,
+ 0,
+ 0);
+
+ NtGdiDeleteObjectApp(hdc);
+ DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi);
+ }
+ else
+ {
+ DPRINT1("Unknown file type!\n");
+ }
+
+leave:
/* Unmap our section, we don't need it anymore */
ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh);
#define NDEBUG
#include <debug.h>
+NTSTATUS
+NTAPI
+RegOpenKey(
+ LPCWSTR pwszKeyName,
+ PHKEY phkey)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING ustrKeyName;
+ HKEY hkey;
+
+ /* Initialize the key name */
+ RtlInitUnicodeString(&ustrKeyName, pwszKeyName);
+
+ /* Initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ustrKeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ /* Open the key */
+ Status = ZwOpenKey(&hkey, KEY_READ, &ObjectAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ *phkey = hkey;
+ }
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+RegQueryValue(
+ IN HKEY hkey,
+ IN PCWSTR pwszValueName,
+ IN ULONG ulType,
+ OUT PVOID pvData,
+ IN OUT PULONG pcbValue)
+{
+ NTSTATUS Status;
+ UNICODE_STRING ustrValueName;
+ BYTE ajBuffer[100];
+ PKEY_VALUE_PARTIAL_INFORMATION pInfo;
+ ULONG cbInfoSize, cbDataSize;
+
+ /* Check if the local buffer is sufficient */
+ cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue;
+ if (cbInfoSize <= sizeof(ajBuffer))
+ {
+ pInfo = (PVOID)ajBuffer;
+ }
+ else
+ {
+ /* It's not, allocate a sufficient buffer */
+ pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
+ if (!pInfo)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+
+ /* Query the value */
+ RtlInitUnicodeString(&ustrValueName, pwszValueName);
+ Status = ZwQueryValueKey(hkey,
+ &ustrValueName,
+ KeyValuePartialInformation,
+ (PVOID)pInfo,
+ cbInfoSize,
+ &cbInfoSize);
+
+ cbDataSize = cbInfoSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* Did we get the right type */
+ if (pInfo->Type == ulType)
+ {
+ /* Copy the contents to the caller */
+ RtlCopyMemory(pvData, pInfo->Data, min(*pcbValue, cbDataSize));
+ }
+ else
+ Status = STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ /* Return the data size to the caller */
+ *pcbValue = cbDataSize;
+
+ /* Cleanup */
+ if (pInfo != (PVOID)ajBuffer)
+ ExFreePoolWithTag(pInfo, TAG_TEMP);
+
+ return Status;
+
+}
+
+VOID
+NTAPI
+RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData)
+{
+ UNICODE_STRING ustrValue;
+ UNICODE_STRING ustrData;
+
+ RtlInitUnicodeString(&ustrValue, pwszValue);
+ RtlInitUnicodeString(&ustrData, pwszData);
+ ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR));
+}
+
+VOID
+NTAPI
+RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData)
+{
+ UNICODE_STRING ustrValue;
+
+ RtlInitUnicodeString(&ustrValue, pwszValue);
+ ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD));
+}
+
+BOOL
+NTAPI
+RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData)
+{
+ NTSTATUS Status;
+ ULONG cbSize = sizeof(DWORD);
+ Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize);
+ return NT_SUCCESS(Status);
+}
+
BOOL
NTAPI
RegReadUserSetting(
Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n", Status, usKeyName.Length, usKeyName.MaximumLength);
+ DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n",
+ Status, usKeyName.Length, usKeyName.MaximumLength);
return FALSE;
}
- /*
+/*
* PROJECT: ReactOS Win32 Subsystem
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/win32k/ntddraw/dxeng.c
break;
case DxEGShDevData_hSpooler:
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_hSpooler\n");
- // retVal = (DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
- retVal = (DWORD_PTR) PDev->VideoFileObject->DeviceObject;
+ retVal = 0;//(DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver.
break;
case DxEGShDevData_DitherFmt:
DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_DitherFmt\n");
/*==============================================================*/
HANDLE FASTCALL
-renderBITMAPfromDIB(LPBYTE hDIB)
+renderBITMAPfromDIB(LPBYTE pDIB)
{
HDC hdc;
HBITMAP hbitmap;
- unsigned int offset;
- BITMAPINFOHEADER *ih;
+ PBITMAPINFO pBmi, pConvertedBmi = NULL;
+ NTSTATUS Status ;
+ UINT offset = 0; /* Stupid compiler */
+
+ pBmi = (BITMAPINFO*)pDIB;
//hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE);
- ih = (BITMAPINFOHEADER *)hDIB;
-
- offset = sizeof(BITMAPINFOHEADER) + ((ih->biBitCount <= 8) ? (sizeof(RGBQUAD) * (1 << ih->biBitCount)) : 0);
-
- hbitmap = NtGdiCreateDIBitmapInternal(hdc,
- ih->biWidth,
- ih->biHeight,
- CBM_INIT,
- (LPBYTE)ih+offset,
- (LPBITMAPINFO)ih,
- DIB_RGB_COLORS,
- ih->biBitCount,
- ih->biSizeImage,
- 0,
- 0);
+ /* Probe it */
+ _SEH2_TRY
+ {
+ ProbeForRead(&pBmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(pBmi, pBmi->bmiHeader.biSize, 1);
+ ProbeForRead(pBmi, DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS), 1);
+ pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS);
+ if(!pConvertedBmi)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ offset = DIB_BitmapInfoSize((BITMAPINFO*)pBmi, DIB_RGB_COLORS);
+ ProbeForRead(pDIB + offset, pConvertedBmi->bmiHeader.biSizeImage, 1);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ UserReleaseDC(ClipboardWindow, hdc, FALSE);
+ return NULL;
+ }
+
+ hbitmap = GreCreateDIBitmapInternal(hdc,
+ pConvertedBmi->bmiHeader.biWidth,
+ pConvertedBmi->bmiHeader.biHeight,
+ CBM_INIT,
+ pDIB+offset,
+ pConvertedBmi,
+ DIB_RGB_COLORS,
+ 0,
+ 0);
//UserReleaseDC(NULL, hdc, FALSE);
UserReleaseDC(ClipboardWindow, hdc, FALSE);
+ DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi);
+
return hbitmap;
}
PCURICON_OBJECT OldCursor;
HCURSOR hOldCursor = (HCURSOR)0;
HDC hdcScreen;
-
+
CurInfo = IntGetSysCursorInfo();
OldCursor = CurInfo->CurrentCursorObject;
}
+
/*
* @implemented
*/
END_CLEANUP;
}
-
-/*
- * @implemented
- */
BOOL
APIENTRY
-NtUserClipCursor(
- RECTL *UnsafeRect)
+UserClipCursor(
+ RECTL *prcl)
{
/* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
PSYSTEM_CURSORINFO CurInfo;
- RECTL Rect;
PWND DesktopWindow = NULL;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserClipCursor\n");
- UserEnterExclusive();
-
- if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN(FALSE);
- }
CurInfo = IntGetSysCursorInfo();
DesktopWindow = UserGetDesktopWindow();
- if ((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
- && DesktopWindow && UnsafeRect != NULL)
+ if (prcl != NULL &&
+ (prcl->right > prcl->left) &&
+ (prcl->bottom > prcl->top) &&
+ DesktopWindow != NULL)
{
-
CurInfo->bClipped = TRUE;
- RECTL_bIntersectRect(&CurInfo->rcClip, &Rect, &DesktopWindow->rcWindow);
+ RECTL_bIntersectRect(&CurInfo->rcClip, prcl, &DesktopWindow->rcWindow);
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
+ }
+ else
+ {
+ CurInfo->bClipped = FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserClipCursor(
+ RECTL *prcl)
+{
+ RECTL rclLocal;
+ BOOL bResult;
+
+ if (prcl)
+ {
+ _SEH2_TRY
+ {
+ /* Probe and copy rect */
+ ProbeForRead(prcl, sizeof(RECTL), 1);
+ rclLocal = *prcl;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ _SEH2_YIELD(return FALSE;)
+ }
+ _SEH2_END
- RETURN(TRUE);
+ prcl = &rclLocal;
}
+
+ UserEnterExclusive();
- CurInfo->bClipped = FALSE;
- RETURN(TRUE);
+ /* Call the internal function */
+ bResult = UserClipCursor(prcl);
-CLEANUP:
- DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_);
UserLeave();
- END_CLEANUP;
+
+ return bResult;
}
/* Delete old bitmaps */
if ((CurIcon->IconInfo.hbmColor)
- && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
+ && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
{
GreDeleteObject(CurIcon->IconInfo.hbmColor);
}
if ((CurIcon->IconInfo.hbmMask)
- && (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask))
+ && CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
{
GreDeleteObject(CurIcon->IconInfo.hbmMask);
}
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy / 2;
SURFACE_UnlockSurface(psurfBmp);
- GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
}
+ GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
Ret = TRUE;
if(bAlpha && (diFlags & DI_IMAGE))
{
BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
- DWORD Pixel;
- BYTE Red, Green, Blue, Alpha;
- DWORD Count = 0;
+ BYTE Alpha;
INT i, j;
PSURFACE psurf;
- PBYTE pBits ;
+ PBYTE ptr ;
HBITMAP hMemBmp = NULL;
- pBits = ExAllocatePoolWithTag(PagedPool,
- bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
- TAG_BITMAP);
- if (pBits == NULL)
- {
- Ret = FALSE;
- goto CleanupAlpha;
- }
-
hMemBmp = BITMAP_CopyBitmap(hbmColor);
if(!hMemBmp)
{
DPRINT1("SURFACE_LockSurface failed!\n");
goto CleanupAlpha;
}
- /* get color bits */
- IntGetBitmapBits(psurf,
- bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
- pBits);
/* premultiply with the alpha channel value */
- for (i = 0; i < abs(bmpColor.bmHeight); i++)
+ for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++)
{
- Count = i*bmpColor.bmWidthBytes;
- for (j = 0; j < bmpColor.bmWidth; j++)
+ ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta;
+ for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++)
{
- Pixel = *(DWORD *)(pBits + Count);
-
- Alpha = ((BYTE)(Pixel >> 24) & 0xff);
+ Alpha = ptr[3];
+ ptr[0] = (ptr[0] * Alpha) / 0xff;
+ ptr[1] = (ptr[1] * Alpha) / 0xff;
+ ptr[2] = (ptr[2] * Alpha) / 0xff;
- Red = (((BYTE)(Pixel >> 0)) * Alpha) / 0xff;
- Green = (((BYTE)(Pixel >> 8)) * Alpha) / 0xff;
- Blue = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff;
-
- *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
-
- Count += sizeof(DWORD);
+ ptr += 4;
}
}
- /* set mem bits */
- IntSetBitmapBits(psurf,
- bmpColor.bmWidthBytes * abs(bmpColor.bmHeight),
- pBits);
SURFACE_UnlockSurface(psurf);
hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp);
NULL);
NtGdiSelectBitmap(hMemDC, hTmpBmp);
CleanupAlpha:
- if(pBits) ExFreePoolWithTag(pBits, TAG_BITMAP);
if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp);
if(Ret) goto done;
}
-
if (diFlags & DI_MASK)
{
hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask);
{
PWND Window = NULL;
- UserEnterExclusive();
-
Window = UserGetDesktopWindow();
IntInvalidateWindows( Window,
RDW_ERASE |
RDW_INVALIDATE |
RDW_ALLCHILDREN);
- UserLeave();
}
/*
- * PROJECT: ReactOS Kernel
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/win32/win32k/ntuser/display.c
- * PURPOSE: display settings
- * COPYRIGHT: Copyright 2007 ReactOS
- *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * PURPOSE: Video initialization and display settings
+ * FILE: subsystems/win32/win32k/ntuser/display.c
+ * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
-/* INCLUDES ******************************************************************/
-
#include <win32k.h>
+#include <intrin.h>
+
#define NDEBUG
#include <debug.h>
-#define SIZEOF_DEVMODEW_300 188
-#define SIZEOF_DEVMODEW_400 212
-#define SIZEOF_DEVMODEW_500 220
+BOOL InitSysParams();
+
+BOOL gbBaseVideo = 0;
+
+static const PWCHAR KEY_ROOT = L"";
+static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
+
+VOID
+RegWriteDisplaySettings(HKEY hkey, PDEVMODEW pdm)
+{
+ RegWriteDWORD(hkey, L"DefaultSettings.BitsPerPel", pdm->dmBitsPerPel);
+ RegWriteDWORD(hkey, L"DefaultSettings.XResolution", pdm->dmPelsWidth);
+ RegWriteDWORD(hkey, L"DefaultSettings.YResolution", pdm->dmPelsHeight);
+ RegWriteDWORD(hkey, L"DefaultSettings.Flags", pdm->dmDisplayFlags);
+ RegWriteDWORD(hkey, L"DefaultSettings.VRefresh", pdm->dmDisplayFrequency);
+ RegWriteDWORD(hkey, L"DefaultSettings.XPanning", pdm->dmPanningWidth);
+ RegWriteDWORD(hkey, L"DefaultSettings.YPanning", pdm->dmPanningHeight);
+ RegWriteDWORD(hkey, L"DefaultSettings.Orientation", pdm->dmDisplayOrientation);
+ RegWriteDWORD(hkey, L"DefaultSettings.FixedOutput", pdm->dmDisplayFixedOutput);
+ RegWriteDWORD(hkey, L"Attach.RelativeX", pdm->dmPosition.x);
+ RegWriteDWORD(hkey, L"Attach.RelativeY", pdm->dmPosition.y);
+// RegWriteDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", pdm->);
+}
+
+VOID
+RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm)
+{
+ DWORD dwValue;
+
+ /* Zero out the structure */
+ RtlZeroMemory(pdm, sizeof(DEVMODEW));
+
+/* Helper macro */
+#define READ(field, str, flag) \
+ if (RegReadDWORD(hkey, L##str, &dwValue)) \
+ { \
+ pdm->field = dwValue; \
+ pdm->dmFields |= flag; \
+ }
+
+ /* Read all present settings */
+ READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL);
+ READ(dmPelsWidth, "DefaultSettings.XResolution", DM_PELSWIDTH);
+ READ(dmPelsHeight, "DefaultSettings.YResolution", DM_PELSHEIGHT);
+ READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS);
+ READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY);
+ READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH);
+ READ(dmPanningHeight, "DefaultSettings.YPanning", DM_PANNINGHEIGHT);
+ READ(dmDisplayOrientation, "DefaultSettings.Orientation", DM_DISPLAYORIENTATION);
+ READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput", DM_DISPLAYFIXEDOUTPUT);
+ READ(dmPosition.x, "Attach.RelativeX", DM_POSITION);
+ READ(dmPosition.y, "Attach.RelativeY", DM_POSITION);
+}
+
+PGRAPHICS_DEVICE
+NTAPI
+InitDisplayDriver(
+ IN PWSTR pwszDeviceName,
+ IN PWSTR pwszRegKey)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ UNICODE_STRING ustrDeviceName, ustrDisplayDrivers, ustrDescription;
+ NTSTATUS Status;
+ WCHAR awcBuffer[128];
+ ULONG cbSize;
+ HKEY hkey;
+ DEVMODEW dmDefault;
+
+ DPRINT1("InitDisplayDriver(%S, %S);\n",
+ pwszDeviceName, pwszRegKey);
+
+ /* Open the driver's registry key */
+ Status = RegOpenKey(pwszRegKey, &hkey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to open registry key: %ls\n", pwszRegKey);
+ return NULL;
+ }
+
+ /* Query the diplay drivers */
+ cbSize = sizeof(awcBuffer) - 10;
+ Status = RegQueryValue(hkey,
+ L"InstalledDisplayDrivers",
+ REG_MULTI_SZ,
+ awcBuffer,
+ &cbSize);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Didn't find 'InstalledDisplayDrivers', status = 0x%lx\n", Status);
+ ZwClose(hkey);
+ return NULL;
+ }
+
+ /* Initialize the UNICODE_STRING */
+ ustrDisplayDrivers.Buffer = awcBuffer;
+ ustrDisplayDrivers.MaximumLength = cbSize;
+ ustrDisplayDrivers.Length = cbSize;
+
+ /* Set Buffer for description and size of remaining buffer */
+ ustrDescription.Buffer = awcBuffer + (cbSize / sizeof(WCHAR));
+ cbSize = sizeof(awcBuffer) - cbSize;
+
+ /* Query the device string */
+ Status = RegQueryValue(hkey,
+ L"Device Description",
+ REG_SZ,
+ ustrDescription.Buffer,
+ &cbSize);
+ if (NT_SUCCESS(Status))
+ {
+ ustrDescription.MaximumLength = cbSize;
+ ustrDescription.Length = cbSize;
+ }
+ else
+ {
+ RtlInitUnicodeString(&ustrDescription, L"<unknown>");
+ }
+
+ /* Query the default settings */
+ RegReadDisplaySettings(hkey, &dmDefault);
+
+ /* Close the registry key */
+ ZwClose(hkey);
+
+ /* Register the device with GDI */
+ RtlInitUnicodeString(&ustrDeviceName, pwszDeviceName);
+ pGraphicsDevice = EngpRegisterGraphicsDevice(&ustrDeviceName,
+ &ustrDisplayDrivers,
+ &ustrDescription,
+ &dmDefault);
+
+ return pGraphicsDevice;
+}
+
+BOOL
+InitVideo(
+ PUNICODE_STRING pustrRegPath,
+ FLONG flags)
+{
+ ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0;
+ WCHAR awcDeviceName[20];
+ WCHAR awcBuffer[256];
+ NTSTATUS Status;
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ ULONG cbValue;
+ HKEY hkey;
+
+ DPRINT1("----------------------------- InitVideo() -------------------------------\n");
+
+ Status = RegOpenKey(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control", &hkey);
+ if (NT_SUCCESS(Status))
+ {
+ cbValue = 256;
+ Status = RegQueryValue(hkey, L"SystemStartOptions", REG_SZ, awcBuffer, &cbValue);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if VGA mode is requested. */
+ if (wcsstr(awcBuffer, L"/BASEVIDEO") != 0)
+ {
+ DPRINT1("VGA mode requested.\n");
+ gbBaseVideo = TRUE;
+ }
+ }
+
+ ZwClose(hkey);
+ }
+
+ /* Open the key for the adapters */
+ Status = RegOpenKey(KEY_VIDEO, &hkey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not open device registry key!\n");
+ ASSERT(FALSE);
+ }
+
+ /* Read the name of the VGA adapter */
+ cbValue = 20;
+ Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue);
+ if (NT_SUCCESS(Status))
+ {
+ iVGACompatible = _wtoi(&awcDeviceName[13]);
+ DPRINT1("VGA adapter = %ld\n", iVGACompatible);
+ }
+
+ /* Get the maximum mumber of adapters */
+ if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber))
+ {
+ DPRINT1("Could not read MaxObjectNumber, defaulting to 0.\n");
+ }
+
+ DPRINT("Found %ld devices\n", ulMaxObjectNumber);
+
+ /* Loop through all adapters */
+ cbValue = 256;
+ for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++)
+ {
+ /* Create the adapter's key name */
+ swprintf(awcDeviceName, L"\\Device\\Video%lu", iDevNum);
+
+ /* Read the reg key name */
+ Status = RegQueryValue(hkey, awcDeviceName, REG_SZ, awcBuffer, &cbValue);
+
+ pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer);
+
+ /* Check if this is the VGA adapter */
+ if (iDevNum == iVGACompatible)
+ {
+ /* Set the VGA device as primary */
+ gpVgaGraphicsDevice = pGraphicsDevice;
+ DPRINT1("gpVgaGraphicsDevice = %p\n", gpVgaGraphicsDevice);
+ }
+
+ /* Set the first one as primary device */
+ if (!gpPrimaryGraphicsDevice)
+ gpPrimaryGraphicsDevice = pGraphicsDevice;
+ }
+
+ ZwClose(hkey);
+
+ if (gbBaseVideo)
+ {
+ if (gpVgaGraphicsDevice)
+ {
+ /* Set the VgaAdapter as primary */
+ gpPrimaryGraphicsDevice = gpVgaGraphicsDevice;
+ // FIXME: DEVMODE
+ }
+ else
+ {
+ DPRINT1("Could not find VGA compatible driver. Trying normal.\n");
+ }
+ }
+
+ InitSysParams();
-/* PUBLIC FUNCTIONS ***********************************************************/
+ return 1;
+}
NTSTATUS
-APIENTRY
-NtUserEnumDisplaySettings(
- PUNICODE_STRING pusDeviceName,
- DWORD iModeNum,
- LPDEVMODEW lpDevMode, /* FIXME is this correct? */
- DWORD dwFlags )
+NTAPI
+UserEnumDisplayDevices(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ PDISPLAY_DEVICEW pdispdev,
+ DWORD dwFlags)
{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ ULONG cbSize;
+ HKEY hkey;
NTSTATUS Status;
- LPDEVMODEW pSafeDevMode;
- PUNICODE_STRING pusSafeDeviceName = NULL;
- UNICODE_STRING usSafeDeviceName;
- USHORT Size = 0, ExtraSize = 0;
- /* Copy the devmode */
- _SEH2_TRY
+ /* Ask gdi for the GRAPHICS_DEVICE */
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, iDevNum, 0);
+ if (!pGraphicsDevice)
{
- ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
- Size = lpDevMode->dmSize;
- ExtraSize = lpDevMode->dmDriverExtra;
+ /* No device found */
+ DPRINT1("No GRAPHICS_DEVICE found\n");
+ return STATUS_UNSUCCESSFUL;
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+
+ /* Open thhe device map registry key */
+ Status = RegOpenKey(KEY_VIDEO, &hkey);
+ if (!NT_SUCCESS(Status))
{
- DPRINT("FIXME ? : Out of range of DEVMODEW size \n");
- _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ /* No device found */
+ DPRINT1("Could not open reg key\n");
+ return STATUS_UNSUCCESSFUL;
}
- _SEH2_END;
- if (Size != sizeof(DEVMODEW))
+ /* Query the registry path */
+ cbSize = sizeof(pdispdev->DeviceKey);
+ RegQueryValue(hkey,
+ pGraphicsDevice->szNtDeviceName,
+ REG_SZ,
+ pdispdev->DeviceKey,
+ &cbSize);
+
+ /* Close registry key */
+ ZwClose(hkey);
+
+ /* Copy device name, device string and StateFlags */
+ wcsncpy(pdispdev->DeviceName, pGraphicsDevice->szWinDeviceName, 32);
+ wcsncpy(pdispdev->DeviceString, pGraphicsDevice->pwszDescription, 128);
+ pdispdev->StateFlags = pGraphicsDevice->StateFlags;
+
+ // FIXME: fill in DEVICE ID
+
+ return STATUS_SUCCESS;
+}
+
+//NTSTATUS
+BOOL
+NTAPI
+NtUserEnumDisplayDevices(
+ PUNICODE_STRING pustrDevice,
+ DWORD iDevNum,
+ PDISPLAY_DEVICEW pDisplayDevice,
+ DWORD dwFlags)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ DISPLAY_DEVICEW dispdev;
+ NTSTATUS Status;
+
+ DPRINT("Enter NtUserEnumDisplayDevices(%wZ, %ld)\n",
+ pustrDevice, iDevNum);
+
+ // FIXME: HACK, desk.cpl passes broken crap
+ if (pustrDevice && iDevNum != 0)
+ return FALSE;
+
+ dispdev.cb = sizeof(DISPLAY_DEVICEW);
+
+ if (pustrDevice)
{
- return STATUS_BUFFER_TOO_SMALL;
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
+ _SEH2_TRY
+ {
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+// _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ _SEH2_YIELD(return NT_SUCCESS(_SEH2_GetExceptionCode()));
+ }
+ _SEH2_END
+
+ if (ustrDevice.Length > 0)
+ pustrDevice = &ustrDevice;
+ else
+ pustrDevice = NULL;
+ }
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
+ /* Call the internal function */
+ Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags);
+
+ /* Release lock */
+ UserLeave();
+
+ /* On success copy data to caller */
+ if (NT_SUCCESS(Status))
+ {
+ /* Enter SEH */
+ _SEH2_TRY
+ {
+ /* First probe the cb field */
+ ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1);
+
+ /* Check the buffer size */
+ if (pDisplayDevice->cb)
+ {
+ /* Probe the output buffer */
+ pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev));
+ ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1);
+
+ /* Copy as much as the given buffer allows */
+ RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
}
- pSafeDevMode = ExAllocatePoolWithTag(PagedPool, Size + ExtraSize, GDITAG_DEVMODE);
- if (pSafeDevMode == NULL)
+ DPRINT1("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status);
+ /* Return the result */
+// return Status;
+ return NT_SUCCESS(Status); // FIXME
+}
+
+NTSTATUS
+NTAPI
+UserEnumCurrentDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ PDEVMODEW *ppdm)
+{
+ PPDEVOBJ ppdev;
+
+ /* Get the PDEV for the device */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
{
- return STATUS_NO_MEMORY;
+ /* No device found */
+ DPRINT1("No PDEV found!\n");
+ return STATUS_UNSUCCESSFUL;
}
- pSafeDevMode->dmSize = Size;
- pSafeDevMode->dmDriverExtra = ExtraSize;
- /* Copy the device name */
- if (pusDeviceName != NULL)
+ *ppdm = ppdev->pdmwDev;
+ PDEVOBJ_vRelease(ppdev);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+UserEnumDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ DWORD iModeNum,
+ LPDEVMODEW *ppdm,
+ DWORD dwFlags)
+{
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ PDEVMODEENTRY pdmentry;
+ ULONG i, iFoundMode;
+
+ DPRINT("Enter UserEnumDisplaySettings('%ls', %ld)\n",
+ pustrDevice ? pustrDevice->Buffer : NULL, iModeNum);
+
+ /* Ask gdi for the GRAPHICS_DEVICE */
+ pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0);
+
+ if (!pGraphicsDevice)
{
- Status = IntSafeCopyUnicodeString(&usSafeDeviceName, pusDeviceName);
- if (!NT_SUCCESS(Status))
+ /* No device found */
+ DPRINT1("No device found!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (iModeNum >= pGraphicsDevice->cDevModes)
+ return STATUS_NO_MORE_ENTRIES;
+
+ iFoundMode = 0;
+ for (i = 0; i < pGraphicsDevice->cDevModes; i++)
+ {
+ pdmentry = &pGraphicsDevice->pDevModeList[i];
+
+ /* FIXME: consider EDS_RAWMODE */
+#if 0
+ if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) ||!
+ (dwFlags & EDS_RAWMODE))
+#endif
{
- ExFreePool(pSafeDevMode);
- return Status;
+ /* Is this the one we want? */
+ if (iFoundMode == iModeNum)
+ {
+ *ppdm = pdmentry->pdm;
+ return STATUS_SUCCESS;
+ }
+
+ /* Increment number of found modes */
+ iFoundMode++;
}
- pusSafeDeviceName = &usSafeDeviceName;
}
- /* Call internal function */
- Status = IntEnumDisplaySettings(pusSafeDeviceName, iModeNum, pSafeDevMode, dwFlags);
+ /* Nothing was found */
+ return STATUS_INVALID_PARAMETER;
+}
- if (pusSafeDeviceName != NULL)
- RtlFreeUnicodeString(pusSafeDeviceName);
+NTSTATUS
+NTAPI
+UserOpenDisplaySettingsKey(
+ OUT PHKEY phkey,
+ IN PUNICODE_STRING pustrDevice,
+ IN BOOL bGlobal)
+{
+ HKEY hkey;
+ DISPLAY_DEVICEW dispdev;
+ NTSTATUS Status;
+ /* Get device info */
+ Status = UserEnumDisplayDevices(pustrDevice, 0, &dispdev, 0);
if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (bGlobal)
{
- ExFreePool(pSafeDevMode);
+ // FIXME: need to fix the registry key somehow
+ }
+
+ /* Open the registry key */
+ Status = RegOpenKey(dispdev.DeviceKey, &hkey);
+ if (!NT_SUCCESS(Status))
return Status;
+
+ *phkey = hkey;
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+UserEnumRegistryDisplaySettings(
+ IN PUNICODE_STRING pustrDevice,
+ OUT LPDEVMODEW pdm)
+{
+ HKEY hkey;
+ NTSTATUS Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, 0);
+ if(NT_SUCCESS(Status))
+ {
+ RegReadDisplaySettings(hkey, pdm);
+ ZwClose(hkey);
+ return STATUS_SUCCESS;
}
+ return Status ;
+}
+
+
+NTSTATUS
+APIENTRY
+NtUserEnumDisplaySettings(
+ IN PUNICODE_STRING pustrDevice,
+ IN DWORD iModeNum,
+ OUT LPDEVMODEW lpDevMode,
+ IN DWORD dwFlags)
+{
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ NTSTATUS Status;
+ ULONG cbSize, cbExtra;
+ DEVMODEW dmReg, *pdm;
- /* Copy some information back */
- _SEH2_TRY
+ DPRINT1("Enter NtUserEnumDisplaySettings(%ls, %ld)\n",
+ pustrDevice ? pustrDevice->Buffer : 0, iModeNum);
+
+ if (pustrDevice)
{
- ProbeForWrite(lpDevMode,Size + ExtraSize, 1);
- lpDevMode->dmPelsWidth = pSafeDevMode->dmPelsWidth;
- lpDevMode->dmPelsHeight = pSafeDevMode->dmPelsHeight;
- lpDevMode->dmBitsPerPel = pSafeDevMode->dmBitsPerPel;
- lpDevMode->dmDisplayFrequency = pSafeDevMode->dmDisplayFrequency;
- lpDevMode->dmDisplayFlags = pSafeDevMode->dmDisplayFlags;
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
- /* output private/extra driver data */
- if (ExtraSize > 0)
+ _SEH2_TRY
{
- memcpy((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize);
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
}
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END
+
+ pustrDevice = &ustrDevice;
+ }
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
+ if (iModeNum == ENUM_REGISTRY_SETTINGS)
+ {
+ /* Get the registry settings */
+ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
+ pdm = &dmReg;
}
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ else if (iModeNum == ENUM_CURRENT_SETTINGS)
{
- Status = _SEH2_GetExceptionCode();
+ /* Get the current settings */
+ Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm);
+ }
+ else
+ {
+ /* Get specified settings */
+ Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags);
+ }
+
+ /* Release lock */
+ UserLeave();
+
+ /* Did we succeed? */
+ if (NT_SUCCESS(Status))
+ {
+ /* Copy some information back */
+ _SEH2_TRY
+ {
+ ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1);
+ cbSize = lpDevMode->dmSize;
+ cbExtra = lpDevMode->dmDriverExtra;
+
+ ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
+ /* Output what we got */
+ RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize));
+
+ /* output private/extra driver data */
+ if (cbExtra > 0 && pdm->dmDriverExtra > 0)
+ {
+ RtlCopyMemory((PCHAR)lpDevMode + cbSize,
+ (PCHAR)pdm + pdm->dmSize,
+ min(cbExtra, pdm->dmDriverExtra));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
}
- _SEH2_END;
- ExFreePool(pSafeDevMode);
return Status;
}
+BOOL APIENTRY UserClipCursor(RECTL *prcl);
+VOID APIENTRY UserRedrawDesktop();
+HCURSOR FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange);
LONG
APIENTRY
-NtUserChangeDisplaySettings(
- PUNICODE_STRING lpszDeviceName,
- LPDEVMODEW lpDevMode,
+UserChangeDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ LPDEVMODEW pdm,
HWND hwnd,
- DWORD dwflags,
+ DWORD flags,
LPVOID lParam)
{
- NTSTATUS Status = STATUS_SUCCESS;
- LPDEVMODEW lpSafeDevMode = NULL;
- DEVMODEW DevMode;
- PUNICODE_STRING pSafeDeviceName = NULL;
- UNICODE_STRING SafeDeviceName;
- LONG Ret;
-
- /* Check arguments */
-#ifdef CDS_VIDEOPARAMETERS
- if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL)
-#else
- if (lParam != NULL)
-#endif
+ DEVMODEW dm;
+ LONG lResult = DISP_CHANGE_SUCCESSFUL;
+ HKEY hkey;
+ NTSTATUS Status;
+ PPDEVOBJ ppdev;
+ PDESKTOP pdesk;
+
+ /* If no DEVMODE is given, use registry settings */
+ if (!pdm)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ /* Get the registry settings */
+ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dm);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not load registry settings\n");
+ return DISP_CHANGE_BADPARAM;
+ }
+ }
+ else if (pdm->dmSize < FIELD_OFFSET(DEVMODEW, dmFields))
+ return DISP_CHANGE_BADMODE; /* This is what winXP SP3 returns */
+ else
+ dm = *pdm;
+
+ /* Check params */
+ if ((dm.dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
+ {
+ DPRINT1("devmode doesn't specify the resolution.\n");
+ return DISP_CHANGE_BADMODE;
+ }
+
+ /* Get the PDEV */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
+ {
+ DPRINT1("failed to get PDEV\n");
return DISP_CHANGE_BADPARAM;
}
- if (hwnd != NULL)
+ /* Fixup values */
+ if(dm.dmBitsPerPel == 0 || !(dm.dmFields & DM_BITSPERPEL))
+ {
+ dm.dmBitsPerPel = ppdev->pdmwDev->dmBitsPerPel;
+ dm.dmFields |= DM_BITSPERPEL;
+ }
+
+ if((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0))
+ dm.dmDisplayFrequency = ppdev->pdmwDev->dmDisplayFrequency;
+
+ /* Look for the requested DEVMODE */
+ pdm = PDEVOBJ_pdmMatchDevMode(ppdev, &dm);
+ if (!pdm)
+ {
+ DPRINT1("Could not find a matching DEVMODE\n");
+ lResult = DISP_CHANGE_BADMODE;
+ goto leave;
+ }
+ else if (flags & CDS_TEST)
+ {
+ /* It's possible, go ahead! */
+ lResult = DISP_CHANGE_SUCCESSFUL;
+ goto leave;
+ }
+
+ /* Shall we update the registry? */
+ if (flags & CDS_UPDATEREGISTRY)
+ {
+ /* Open the local or global settings key */
+ Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, flags & CDS_GLOBAL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Store the settings */
+ RegWriteDisplaySettings(hkey, pdm);
+
+ /* Close the registry key */
+ ZwClose(hkey);
+ }
+ else
+ {
+ DPRINT1("Could not open registry key\n");
+ lResult = DISP_CHANGE_NOTUPDATED;
+ }
+ }
+
+ /* Check if DEVMODE matches the current mode */
+ if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET))
+ {
+ DPRINT1("DEVMODE matches, nothing to do\n");
+ goto leave;
+ }
+
+ /* Shall we apply the settings? */
+ if (!(flags & CDS_NORESET))
+ {
+ ULONG ulResult;
+
+ /* Remove mouse pointer */
+ UserSetCursor(NULL, TRUE);
+
+ /* Do the mode switch */
+ ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm);
+
+ /* Restore mouse pointer, no hooks called */
+ UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
+
+ /* Check for failure */
+ if (!ulResult)
+ {
+ DPRINT1("failed to set mode\n");
+ lResult = (lResult == DISP_CHANGE_NOTUPDATED) ?
+ DISP_CHANGE_FAILED : DISP_CHANGE_RESTART;
+
+ goto leave;
+ }
+
+ /* Update the system metrics */
+ InitMetrics();
+
+ //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
+
+ /* Remove all cursor clipping */
+ UserClipCursor(NULL);
+
+ pdesk = IntGetActiveDesktop();
+ //IntHideDesktop(pdesk);
+
+ /* Send WM_DISPLAYCHANGE to all toplevel windows */
+ co_IntSendMessageTimeout(HWND_BROADCAST,
+ WM_DISPLAYCHANGE,
+ (WPARAM)ppdev->gdiinfo.cBitsPixel,
+ (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulVertRes << 16)),
+ SMTO_NORMAL,
+ 100,
+ &ulResult);
+
+ //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
+
+ UserRedrawDesktop();
+ }
+
+leave:
+ /* Release the PDEV */
+ PDEVOBJ_vRelease(ppdev);
+
+ return lResult;
+}
+
+LONG
+APIENTRY
+NtUserChangeDisplaySettings(
+ PUNICODE_STRING pustrDevice,
+ LPDEVMODEW lpDevMode,
+ HWND hwnd,
+ DWORD dwflags,
+ LPVOID lParam)
+{
+ WCHAR awcDevice[CCHDEVICENAME];
+ UNICODE_STRING ustrDevice;
+ DEVMODEW dmLocal;
+ LONG lRet;
+
+ /* Check arguments */
+ if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) ||
+ (hwnd != NULL))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return DISP_CHANGE_BADPARAM;
}
- /* Copy devmode */
- if (lpDevMode != NULL)
+ /* Check flags */
+ if ((dwflags & (CDS_GLOBAL|CDS_NORESET)) && !(dwflags & CDS_UPDATEREGISTRY))
+ {
+ return DISP_CHANGE_BADFLAGS;
+ }
+
+ /* Copy the device name */
+ if (pustrDevice)
{
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
_SEH2_TRY
{
- ProbeForRead(lpDevMode, sizeof(DevMode.dmSize), 1);
- DevMode.dmSize = lpDevMode->dmSize;
- DevMode.dmSize = min(sizeof(DevMode), DevMode.dmSize);
- ProbeForRead(lpDevMode, DevMode.dmSize, 1);
- RtlCopyMemory(&DevMode, lpDevMode, DevMode.dmSize);
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH2_GetExceptionCode();
+ /* Set and return error */
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
}
_SEH2_END
- if (!NT_SUCCESS(Status))
+ pustrDevice = &ustrDevice;
+ }
+
+ /* Copy devmode */
+ if (lpDevMode)
+ {
+ _SEH2_TRY
{
- SetLastNtError(Status);
- return DISP_CHANGE_BADPARAM;
- }
+ /* Probe the size field of the structure */
+ ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1);
- if (DevMode.dmDriverExtra > 0)
+ /* Calculate usable size */
+ dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize);
+
+ /* Probe and copy the full DEVMODE */
+ ProbeForRead(lpDevMode, dmLocal.dmSize, 1);
+ RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
- DevMode.dmDriverExtra = 0;
+ /* Set and return error */
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return DISP_CHANGE_BADPARAM);
}
- lpSafeDevMode = &DevMode;
- }
+ _SEH2_END
- /* Copy the device name */
- if (lpszDeviceName != NULL)
- {
- Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
- if (!NT_SUCCESS(Status))
+ /* Check for extra parameters */
+ if (dmLocal.dmDriverExtra > 0)
{
- SetLastNtError(Status);
- return DISP_CHANGE_BADPARAM;
+ /* FIXME: TODO */
+ DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n");
+ dmLocal.dmDriverExtra = 0;
}
- pSafeDeviceName = &SafeDeviceName;
+
+ /* Use the local structure */
+ lpDevMode = &dmLocal;
}
+ // FIXME: Copy videoparameters
+
+ /* Acquire global USER lock */
+ UserEnterExclusive();
+
/* Call internal function */
- Ret = IntChangeDisplaySettings(pSafeDeviceName, lpSafeDevMode, dwflags, lParam);
+ lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL);
- if (pSafeDeviceName != NULL)
- RtlFreeUnicodeString(pSafeDeviceName);
+ /* Release lock */
+ UserLeave();
- return Ret;
+ return lRet;
}
DPRINT("Loaded %wZ\n", &FullLayoutPath);
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
- LdrGetProcedureAddress((*(PDRIVERS*)phModule)->BaseAddress,
- &kbdProcedureName,
- 0,
- (PVOID*)&layerDescGetFn);
+ layerDescGetFn = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
if(layerDescGetFn)
{
KeQueryTickCount(&TickCount);
Time = MsqCalculateMessageTime(&TickCount);
retval = co_IntCallWindowProc((WNDPROC)pMsg->lParam,
- TRUE,
- pMsg->hwnd,
- WM_TIMER,
- pMsg->wParam,
- (LPARAM)Time,
- sizeof(LPARAM));
+ TRUE,
+ pMsg->hwnd,
+ WM_TIMER,
+ pMsg->wParam,
+ (LPARAM)Time,
+ sizeof(LPARAM));
}
ObDereferenceObject(pti->pEThread);
return retval;
}
}
- if ( gspv.bMouseClickLock &&
+ if ( gspv.bMouseClickLock &&
( (Msg->message == WM_LBUTTONUP) ||
(Msg->message == WM_LBUTTONDOWN) ) )
{
do
{
- KeQueryTickCount(&LargeTickCount);
- ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
-
- /* Dispatch sent messages here. */
- while (co_MsqDispatchOneSentMessage(ThreadQueue))
- ;
-
- /* Now look for a quit message. */
-
- if (ThreadQueue->QuitPosted)
- {
- /* According to the PSDK, WM_QUIT messages are always returned, regardless
- of the filter specified */
- Msg->Msg.hwnd = NULL;
- Msg->Msg.message = WM_QUIT;
- Msg->Msg.wParam = ThreadQueue->QuitExitCode;
- Msg->Msg.lParam = 0;
- if (RemoveMessages)
- {
- ThreadQueue->QuitPosted = FALSE;
- }
+ KeQueryTickCount(&LargeTickCount);
+ ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
+
+ /* Dispatch sent messages here. */
+ while (co_MsqDispatchOneSentMessage(ThreadQueue))
+ ;
+
+ /* Now look for a quit message. */
+
+ if (ThreadQueue->QuitPosted)
+ {
+ /* According to the PSDK, WM_QUIT messages are always returned, regardless
+ of the filter specified */
+ Msg->Msg.hwnd = NULL;
+ Msg->Msg.message = WM_QUIT;
+ Msg->Msg.wParam = ThreadQueue->QuitExitCode;
+ Msg->Msg.lParam = 0;
+ if (RemoveMessages)
+ {
+ ThreadQueue->QuitPosted = FALSE;
+ }
return TRUE;
- }
+ }
- /* Now check for normal messages. */
+ /* Now check for normal messages. */
if (co_MsqFindMessage( ThreadQueue,
- FALSE,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
+ FALSE,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
&Message ))
- {
- RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
- if (RemoveMessages)
- {
- MsqDestroyMessage(Message);
- }
+ {
+ RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
+ if (RemoveMessages)
+ {
+ MsqDestroyMessage(Message);
+ }
break;
- }
+ }
- /* Check for hardware events. */
+ /* Check for hardware events. */
if(co_MsqFindMessage( ThreadQueue,
- TRUE,
- RemoveMessages,
- Window,
- MsgFilterMin,
- MsgFilterMax,
+ TRUE,
+ RemoveMessages,
+ Window,
+ MsgFilterMin,
+ MsgFilterMax,
&Message ))
- {
- RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
- if (RemoveMessages)
- {
- MsqDestroyMessage(Message);
- }
+ {
+ RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
+ if (RemoveMessages)
+ {
+ MsqDestroyMessage(Message);
+ }
if(!ProcessHardwareMessage(&Msg->Msg, RemoveMessages))
continue;
break;
- }
+ }
- /* Check for sent messages again. */
- while (co_MsqDispatchOneSentMessage(ThreadQueue))
- ;
+ /* Check for sent messages again. */
+ while (co_MsqDispatchOneSentMessage(ThreadQueue))
+ ;
- /* Check for paint messages. */
+ /* Check for paint messages. */
if( IntGetPaintMessage( Window,
- MsgFilterMin,
- MsgFilterMax,
- pti,
- &Msg->Msg,
- RemoveMessages))
- {
+ MsgFilterMin,
+ MsgFilterMax,
+ pti,
+ &Msg->Msg,
+ RemoveMessages))
+ {
break;
- }
+ }
- if (PostTimerMessages(Window))
- {
+ if (PostTimerMessages(Window))
+ {
continue;
- }
+ }
- return FALSE;
- }
+ return FALSE;
+ }
while (TRUE);
- // The WH_GETMESSAGE hook enables an application to monitor messages about to
- // be returned by the GetMessage or PeekMessage function.
+ // The WH_GETMESSAGE hook enables an application to monitor messages about to
+ // be returned by the GetMessage or PeekMessage function.
- co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
- return TRUE;
+ co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
+ return TRUE;
}
static NTSTATUS FASTCALL
return FALSE;
}
- if (!Wnd)
+ if (!Wnd)
return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
Msg,
wParam,
if (List != NULL)
{
+ UserPostMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
UserPostMessage(List[i], Msg, wParam, lParam);
ExFreePool(List);
do
{
Status = co_MsqSendMessage( Window->head.pti->MessageQueue,
- hWnd,
- Msg,
- wParam,
- lParam,
- uTimeout,
- (uFlags & SMTO_BLOCK),
- MSQ_NORMAL,
- uResult );
+ hWnd,
+ Msg,
+ wParam,
+ lParam,
+ uTimeout,
+ (uFlags & SMTO_BLOCK),
+ MSQ_NORMAL,
+ uResult );
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
return 0;
}
+ /* Send message to the desktop window too! */
+ co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+
Children = IntWinListChildren(DesktopWindow);
if (NULL == Children)
{
if (List != NULL)
{
+ UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
{
UserSendNotifyMessage(List[i], Msg, wParam, lParam);
BOOL Hit = FALSE;
MSG SafeMsg;
- UserEnterExclusive();
+ UserEnterExclusive();
_SEH2_TRY
{
ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
Hit = TRUE;
}
_SEH2_END;
-
+
if (!Hit) Res = IntDispatchMessage(&SafeMsg);
UserLeave();
{
BadChk = TRUE;
}
- _SEH2_END;
+ _SEH2_END;
}
break;
default:
- break;
+ break;
}
UserLeave();
InitMetrics(VOID)
{
INT *piSysMet;
+ ULONG Width, Height;
- ULONG Width = pPrimarySurface->gdiinfo.ulHorzRes;
- ULONG Height = pPrimarySurface->gdiinfo.ulVertRes;
+ /* FIXME: HACK, due to missing PDEV on first init */
+ if (!pPrimarySurface)
+ {
+ Width = 640;
+ Height = 480;
+ }
+ else
+ {
+ Width = pPrimarySurface->gdiinfo.ulHorzRes;
+ Height = pPrimarySurface->gdiinfo.ulVertRes;
+ }
piSysMet = gpsi->aiSysMet;
return 0;
}
-BOOL
-APIENTRY
-NtUserEnumDisplayDevices (
- PUNICODE_STRING lpDevice, /* device name */
- DWORD iDevNum, /* display device */
- PDISPLAY_DEVICEW lpDisplayDevice, /* device information */
- DWORD dwFlags ) /* reserved */
-{
- DPRINT1("NtUserEnumDisplayDevices() is UNIMPLEMENTED!\n");
- if (lpDevice->Length == 0 && iDevNum > 0)
- {
- /* Only one display device present */
- return FALSE;
- }
- else if (lpDevice->Length != 0)
- {
- /* Can't enumerate monitors :( */
- return FALSE;
- }
- if (lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
- return FALSE;
-
- wcscpy(lpDisplayDevice->DeviceName, L"\\\\.\\DISPLAY1");
- wcscpy(lpDisplayDevice->DeviceString, L"<Unknown>");
- lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
- | DISPLAY_DEVICE_MODESPRUNED
- | DISPLAY_DEVICE_PRIMARY_DEVICE
- | DISPLAY_DEVICE_VGA_COMPATIBLE;
- lpDisplayDevice->DeviceID[0] = L'0';
- lpDisplayDevice->DeviceKey[0] = L'0';
- return TRUE;
-}
-
DWORD
APIENTRY
NtUserEvent(
return Status;
}
- if (!gpsi)
- {
- gpsi = UserHeapAlloc(sizeof(SERVERINFO));
- if (gpsi)
- {
- RtlZeroMemory(gpsi, sizeof(SERVERINFO));
- DPRINT("Global Server Data -> %x\n", gpsi);
- }
- }
-
InitUserAtoms();
InitSysParams();
return STATUS_SUCCESS;
}
+BOOL
+InitVideo(ULONG);
NTSTATUS
NTAPI
// Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA)
// Create Object Directory,,, Looks like create workstation. "\\Windows\\WindowStations"
// Create Event for Diconnect Desktop.
+ InitVideo(0);
// Initialize Video.
// {
// DrvInitConsole.
{
NTSTATUS Status;
- DPRINT("Enter NtUserInitialize(%lx, %p, %p)\n",
- dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
+ DPRINT1("Enter NtUserInitialize(%lx, %p, %p)\n",
+ dwWinVersion, hPowerRequestEvent, hMediaRequestEvent);
/* Check the Windows version */
if (dwWinVersion != 0)
UNICODE_STRING DriverName;
RtlInitUnicodeString(&DriverName, L"DISPLAY");
hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
+
+ co_IntGraphicsCheck(TRUE);
+
//
// If NULL, first time through! Build the default window dc!
//
static
BOOL
FASTCALL
-IntArc( DC *dc,
+IntArc( DC *dc,
int Left,
int Top,
int Right,
}
if (!PenWidth) PenWidth = 1;
- pbrushPen->ptPenWidth.x = PenWidth;
+ pbrushPen->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.right = Right;
IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
IntLPtoDP(dc, (LPPOINT)&RectSEpts, 2);
-
+
RectBounds.left += dc->ptlDCOrig.x;
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.top += dc->ptlDCOrig.y;
}
if (arctype == GdiTypeChord)
PUTLINE(EfCx + CenterX, EfCy + CenterY, SfCx + CenterX, SfCy + CenterY, dc->eboLine);
-
+
pbrushPen->ptPenWidth.x = PenOrigWidth;
PEN_UnlockPen(pbrushPen);
DPRINT("IntArc Exit.\n");
pdcattr = dc->pdcattr;
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(dc);
-
- if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(dc);
-
if (arctype == GdiTypeArcTo)
{
if (dc->dclevel.flPath & DCPATH_CLOCKWISE)
}
worker.l = dwStartAngle;
worker1.l = dwSweepAngle;
+ DC_vPrepareDCsForBlit(pDC, pDC->rosdc.CombinedClip->rclBounds,
+ NULL, pDC->rosdc.CombinedClip->rclBounds);
+ if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(pDC);
+ if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(pDC);
Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f);
+ DC_vFinishBlit(pDC, NULL);
DC_UnlockDc( pDC );
return Ret;
}
return TRUE;
}
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
Ret = IntGdiArcInternal(
arctype,
dc,
XEndArc,
YEndArc);
+ DC_vFinishBlit(dc, NULL);
DC_UnlockDc( dc );
return Ret;
}
{
PDC DCDest;
PDC DCSrc;
+ HDC ahDC[2];
+ PGDIOBJ apObj[2];
SURFACE *BitmapDest, *BitmapSrc;
RECTL DestRect, SourceRect;
BOOL bResult;
return FALSE;
}
- DCDest = DC_LockDc(hDCDest);
- if (NULL == DCDest)
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hDCDest;
+ ahDC[1] = hDCSrc ;
+ GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
+
+ if ((NULL == DCDest) || (NULL == DCSrc))
{
- DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest);
+ DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return FALSE;
}
- if (DCDest->dctype == DC_TYPE_INFO)
+ if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
{
- DC_UnlockDc(DCDest);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
- if (hDCSrc != hDCDest)
- {
- DCSrc = DC_LockDc(hDCSrc);
- if (NULL == DCSrc)
- {
- DC_UnlockDc(DCDest);
- DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (DCSrc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
- }
- else
- {
- DCSrc = DCDest;
- }
-
DestRect.left = XOriginDest;
DestRect.top = YOriginDest;
DestRect.right = XOriginDest + WidthDest;
!SourceRect.right ||
!SourceRect.bottom)
{
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return TRUE;
}
+ /* Prepare DCs for blit */
+ DPRINT("Preparing DCs for blit\n");
+ DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (!BitmapDest)
{
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- return FALSE;
+ bResult = FALSE ;
+ goto leave ;
}
BitmapSrc = DCSrc->dclevel.pSurface;
if (!BitmapSrc)
{
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- return FALSE;
+ bResult = FALSE;
+ goto leave;
}
/* Create the XLATEOBJ. */
EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
/* Perform the alpha blend operation */
+ DPRINT("Performing the alpha Blend\n");
bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
&BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip,
&BlendObj);
EXLATEOBJ_vCleanup(&exlo);
- DC_UnlockDc(DCDest);
- if (hDCSrc != hDCDest)
- DC_UnlockDc(DCSrc);
+leave :
+ DPRINT("Finishing blit\n");
+ DC_vFinishBlit(DCDest, DCSrc);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return bResult;
}
{
PDC DCDest;
PDC DCSrc = NULL;
+ HDC ahDC[2];
+ PGDIOBJ apObj[2];
PDC_ATTR pdcattr = NULL;
SURFACE *BitmapDest, *BitmapSrc = NULL;
- RECTL DestRect;
+ RECTL DestRect, SourceRect;
POINTL SourcePoint;
BOOL Status = FALSE;
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL;
BOOL UsesSource = ROP3_USES_SOURCE(ROP);
- DCDest = DC_LockDc(hDCDest);
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hDCDest;
+ ahDC[1] = hDCSrc ;
+ GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
+
if (NULL == DCDest)
{
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
return FALSE;
}
if (DCDest->dctype == DC_TYPE_INFO)
{
- DC_UnlockDc(DCDest);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
- if (hDCSrc != hDCDest)
+ if (NULL == DCSrc)
{
- DCSrc = DC_LockDc(hDCSrc);
- if (NULL == DCSrc)
- {
- DC_UnlockDc(DCDest);
- DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
- return FALSE;
- }
- if (DCSrc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
+ return FALSE;
}
- else
+ if (DCSrc->dctype == DC_TYPE_INFO)
{
- DCSrc = DCDest;
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ /* Yes, Windows really returns TRUE in this case */
+ return TRUE;
}
}
+ else if(DCSrc)
+ {
+ DPRINT1("Getting a valid Source handle without using source!!!\n");
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ DCSrc = NULL ;
+ }
pdcattr = DCDest->pdcattr;
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(DCDest);
-
DestRect.left = XDest;
DestRect.top = YDest;
DestRect.right = XDest+Width;
SourcePoint.x += DCSrc->ptlDCOrig.x;
SourcePoint.y += DCSrc->ptlDCOrig.y;
+ /* Calculate Source Rect */
+ SourceRect.left = SourcePoint.x;
+ SourceRect.top = SourcePoint.y;
+ SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left;
+ SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ;
}
+ /* Prepare blit */
+ DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(DCDest);
+
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (!BitmapDest)
&DCDest->dclevel.pbrFill->ptOrigin,
ROP3_TO_ROP4(ROP));
- if (UsesSource)
+ if (UsesSource)
EXLATEOBJ_vCleanup(&exlo);
cleanup:
- if (UsesSource && hDCSrc != hDCDest)
+ DC_vFinishBlit(DCDest, DCSrc);
+ if (UsesSource)
{
- DC_UnlockDc(DCSrc);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
}
- DC_UnlockDc(DCDest);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return Status;
}
COLORREF TransColor)
{
PDC DCDest, DCSrc;
+ HDC ahDC[2];
+ PGDIOBJ apObj[2];
RECTL rcDest, rcSrc;
SURFACE *BitmapDest, *BitmapSrc = NULL;
- HPALETTE SourcePalette = 0, DestPalette = 0;
- PPALETTE PalDestGDI, PalSourceGDI;
ULONG TransparentColor = 0;
BOOL Ret = FALSE;
EXLATEOBJ exlo;
- if(!(DCDest = DC_LockDc(hdcDst)))
- {
- DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcDst);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (DCDest->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hdcDst;
+ ahDC[1] = hdcSrc ;
+ GDIOBJ_LockMultipleObjs(2, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
- if((hdcDst != hdcSrc) && !(DCSrc = DC_LockDc(hdcSrc)))
+ if ((NULL == DCDest) || (NULL == DCSrc))
{
- DC_UnlockDc(DCDest);
- DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcSrc);
+ DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
return FALSE;
}
- if(hdcDst == hdcSrc)
- {
- DCSrc = DCDest;
- }
-
- if (DCSrc->dctype == DC_TYPE_INFO)
+ if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
{
- DC_UnlockDc(DCSrc);
- if(hdcDst != hdcSrc)
- {
- DC_UnlockDc(DCDest);
- }
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
- BitmapDest = DCDest->dclevel.pSurface;
- if (!BitmapDest)
- {
- goto done;
- }
-
- BitmapSrc = DCSrc->dclevel.pSurface;
- if (!BitmapSrc)
- {
- goto done;
- }
-
- DestPalette = BitmapDest->hDIBPalette;
- if (!DestPalette) DestPalette = pPrimarySurface->devinfo.hpalDefault;
-
- SourcePalette = BitmapSrc->hDIBPalette;
- if (!SourcePalette) SourcePalette = pPrimarySurface->devinfo.hpalDefault;
-
- if(!(PalSourceGDI = PALETTE_LockPalette(SourcePalette)))
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- goto done;
- }
- PALETTE_UnlockPalette(PalSourceGDI);
-
- if(DestPalette != SourcePalette)
- {
- if (!(PalDestGDI = PALETTE_LockPalette(DestPalette)))
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- goto done;
- }
- PALETTE_UnlockPalette(PalDestGDI);
- }
- else
- {
- PalDestGDI = PalSourceGDI;
- }
-
- /* Translate Transparent (RGB) Color to the source palette */
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalSourceGDI, 0, 0, 0);
- TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor);
- EXLATEOBJ_vCleanup(&exlo);
-
- EXLATEOBJ_vInitialize(&exlo, PalSourceGDI, PalDestGDI, 0, 0, 0);
-
rcDest.left = xDst;
rcDest.top = yDst;
rcDest.right = rcDest.left + cxDst;
rcSrc.right += DCSrc->ptlDCOrig.x;
rcSrc.bottom += DCSrc->ptlDCOrig.y;
+ /* Prepare for blit */
+ DC_vPrepareDCsForBlit(DCDest, rcDest, DCSrc, rcSrc);
+
+ BitmapDest = DCDest->dclevel.pSurface;
+ if (!BitmapDest)
+ {
+ goto done;
+ }
+
+ BitmapSrc = DCSrc->dclevel.pSurface;
+ if (!BitmapSrc)
+ {
+ goto done;
+ }
+
+ /* Translate Transparent (RGB) Color to the source palette */
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, BitmapSrc->ppal, 0, 0, 0);
+ TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor);
+ EXLATEOBJ_vCleanup(&exlo);
+
+ EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
+
Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip, &exlo.xlo, &rcDest, &rcSrc,
TransparentColor, 0);
-done:
- DC_UnlockDc(DCSrc);
- if(hdcDst != hdcSrc)
- {
- DC_UnlockDc(DCDest);
- }
EXLATEOBJ_vCleanup(&exlo);
+
+done:
+ DC_vFinishBlit(DCDest, DCSrc);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+
return Ret;
}
PDC DCDest;
PDC DCSrc = NULL;
PDC DCMask = NULL;
+ HDC ahDC[3];
+ PGDIOBJ apObj[3];
PDC_ATTR pdcattr;
SURFACE *BitmapDest, *BitmapSrc = NULL;
SURFACE *BitmapMask = NULL;
return FALSE;
}
- DCDest = DC_LockDc(hDCDest);
+ DPRINT("Locking DCs\n");
+ ahDC[0] = hDCDest;
+ ahDC[1] = hDCSrc ;
+ ahDC[2] = hDCMask ;
+ GDIOBJ_LockMultipleObjs(3, ahDC, apObj);
+ DCDest = apObj[0];
+ DCSrc = apObj[1];
+ DCMask = apObj[2];
+
if (NULL == DCDest)
{
- DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest);
return FALSE;
}
if (DCDest->dctype == DC_TYPE_INFO)
{
- DC_UnlockDc(DCDest);
+ if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
- if (hDCSrc != hDCDest)
+ if (NULL == DCSrc)
{
- DCSrc = DC_LockDc(hDCSrc);
- if (NULL == DCSrc)
- {
- DC_UnlockDc(DCDest);
- DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (DCSrc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(DCSrc);
- DC_UnlockDc(DCDest);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc);
+ return FALSE;
}
- else
+ if (DCSrc->dctype == DC_TYPE_INFO)
{
- DCSrc = DCDest;
+ GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject);
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject);
+ /* Yes, Windows really returns TRUE in this case */
+ return TRUE;
}
}
+ else if(DCSrc)
+ {
+ DPRINT1("Getting a valid Source handle without using source!!!\n");
+ GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject);
+ DCSrc = NULL ;
+ }
pdcattr = DCDest->pdcattr;
- if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
- DC_vUpdateFillBrush(DCDest);
-
DestRect.left = XOriginDest;
DestRect.top = YOriginDest;
DestRect.right = XOriginDest+WidthDest;
BrushOrigin.x = 0;
BrushOrigin.y = 0;
+ /* Only prepare Source and Dest, hdcMask represents a DIB */
+ DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect);
+
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(DCDest);
+
/* Determine surfaces to be used in the bitblt */
BitmapDest = DCDest->dclevel.pSurface;
if (BitmapDest == NULL)
BrushOrigin.y += DCDest->ptlDCOrig.y;
/* Make mask surface for source surface */
- if (BitmapSrc && hDCMask)
+ if (BitmapSrc && DCMask)
{
- DCMask = DC_LockDc(hDCMask);
- if (DCMask)
+ BitmapMask = DCMask->dclevel.pSurface;
+ if (BitmapMask &&
+ (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
+ BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
{
- BitmapMask = DCMask->dclevel.pSurface;
- if (BitmapMask &&
- (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc ||
- BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc))
- {
- DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
- BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
- WidthSrc, HeightSrc);
- goto failed;
- }
- /* Create mask offset point */
- MaskPoint.x = XOriginMask;
- MaskPoint.y = YOriginMask;
- IntLPtoDP(DCMask, &MaskPoint, 1);
- MaskPoint.x += DCMask->ptlDCOrig.x;
- MaskPoint.y += DCMask->ptlDCOrig.x;
+ DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n",
+ BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy,
+ WidthSrc, HeightSrc);
+ EXLATEOBJ_vCleanup(&exlo);
+ goto failed;
}
+ /* Create mask offset point */
+ MaskPoint.x = XOriginMask;
+ MaskPoint.y = YOriginMask;
+ IntLPtoDP(DCMask, &MaskPoint, 1);
+ MaskPoint.x += DCMask->ptlDCOrig.x;
+ MaskPoint.y += DCMask->ptlDCOrig.x;
}
/* Perform the bitblt operation */
&DCDest->eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(ROP));
-
-failed:
if (UsesSource)
{
EXLATEOBJ_vCleanup(&exlo);
}
- if (UsesSource && hDCSrc != hDCDest)
+
+failed:
+ DC_vFinishBlit(DCDest, DCSrc);
+ if (UsesSource)
{
DC_UnlockDc(DCSrc);
}
{
RECTL DestRect;
SURFACE *psurf;
- EBRUSHOBJ eboFill;
+ EBRUSHOBJ eboFill ;
POINTL BrushOrigin;
BOOL ret;
ASSERT(pbrush);
- psurf = pdc->dclevel.pSurface;
- if (psurf == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
{
return TRUE;
BrushOrigin.x = pbrush->ptOrigin.x + pdc->ptlDCOrig.x;
BrushOrigin.y = pbrush->ptOrigin.y + pdc->ptlDCOrig.y;
+ DC_vPrepareDCsForBlit(pdc, DestRect, NULL, DestRect);
+
+ psurf = pdc->dclevel.pSurface;
+
+ if (pdc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(pdc);
+
EBRUSHOBJ_vInit(&eboFill, pbrush, pdc);
ret = IntEngBitBlt(
&DestRect,
NULL,
NULL,
- &eboFill.BrushObject, // use pDC->eboFill
+ &eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(dwRop));
+ DC_vFinishBlit(pdc, NULL);
+
EBRUSHOBJ_vCleanup(&eboFill);
return ret;
#define NDEBUG
#include <debug.h>
-HBITMAP APIENTRY
-IntGdiCreateBitmap(
- INT Width,
- INT Height,
- UINT Planes,
- UINT BitsPixel,
- IN OPTIONAL LPBYTE pBits)
+LONG APIENTRY
+IntSetBitmapBits(
+ PSURFACE psurf,
+ DWORD Bytes,
+ IN PBYTE Bits)
{
- HBITMAP hBitmap;
- SIZEL Size;
- LONG WidthBytes;
- PSURFACE psurfBmp;
+ /* Don't copy more bytes than the buffer has */
+ Bytes = min(Bytes, psurf->SurfObj.cjBits);
- /* NOTE: Windows also doesn't store nr. of planes separately! */
- BitsPixel = BITMAP_GetRealBitsPixel(BitsPixel * Planes);
+ RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes);
- /* Check parameters */
- if (BitsPixel == 0 || Width <= 0 || Width >= 0x8000000 || Height == 0)
- {
- DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
- Width, Height, BitsPixel);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
+ return Bytes;
+}
- WidthBytes = BITMAP_GetWidthBytes(Width, BitsPixel);
+void
+NTAPI
+UnsafeSetBitmapBits(
+ PSURFACE psurf,
+ IN ULONG cjBits,
+ IN PVOID pvBits)
+{
+ PUCHAR pjDst, pjSrc;
+ LONG lDeltaDst, lDeltaSrc;
+ ULONG nWidth, nHeight, cBitsPixel;
- Size.cx = Width;
- Size.cy = abs(Height);
+ nWidth = psurf->SurfObj.sizlBitmap.cx;
+ nHeight = psurf->SurfObj.sizlBitmap.cy;
+ cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- /* Make sure that cjBits will not overflow */
- if ((ULONGLONG)WidthBytes * Size.cy >= 0x100000000ULL)
- {
- DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
- Width, Height, BitsPixel);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
+ /* Get pointers */
+ pjDst = psurf->SurfObj.pvScan0;
+ pjSrc = pvBits;
+ lDeltaDst = psurf->SurfObj.lDelta;
+ lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
- /* Create the bitmap object. */
- hBitmap = IntCreateBitmap(Size, WidthBytes,
- BitmapFormat(BitsPixel, BI_RGB),
- (Height < 0 ? BMF_TOPDOWN : 0) |
- (NULL == pBits ? 0 : BMF_NOZEROINIT), NULL);
- if (!hBitmap)
+ while (nHeight--)
{
- DPRINT("IntGdiCreateBitmap: returned 0\n");
- return 0;
+ /* Copy one line */
+ memcpy(pjDst, pjSrc, lDeltaSrc);
+ pjSrc += lDeltaSrc;
+ pjDst += lDeltaDst;
}
- psurfBmp = SURFACE_LockSurface(hBitmap);
- if (psurfBmp == NULL)
+}
+
+HBITMAP
+APIENTRY
+GreCreateBitmapEx(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN ULONG cjWidthBytes,
+ IN ULONG iFormat,
+ IN USHORT fjBitmap,
+ IN ULONG cjSizeImage,
+ IN OPTIONAL PVOID pvBits,
+ IN FLONG flags)
+{
+ PSURFACE psurf;
+ SURFOBJ *pso;
+ HBITMAP hbmp;
+ PVOID pvCompressedBits;
+ SIZEL sizl;
+
+ /* Verify format */
+ if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
+
+ /* Allocate a surface */
+ psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
+ if (!psurf)
{
- GreDeleteObject(hBitmap);
+ DPRINT1("SURFACE_AllocSurface failed.\n");
return NULL;
}
- psurfBmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
- psurfBmp->hDC = NULL; // Fixme
+ /* Get the handle for the bitmap and the surfobj */
+ hbmp = (HBITMAP)psurf->SurfObj.hsurf;
+ pso = &psurf->SurfObj;
- if (NULL != pBits)
+ /* The infamous RLE hack */
+ if (iFormat == BMF_4RLE || iFormat == BMF_8RLE)
{
- IntSetBitmapBits(psurfBmp, psurfBmp->SurfObj.cjBits, pBits);
+ sizl.cx = nWidth;
+ sizl.cy = nHeight;
+ pvCompressedBits = pvBits;
+ pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
+ DecompressBitmap(sizl, pvCompressedBits, pvBits, pso->lDelta, iFormat);
+ fjBitmap |= BMF_RLE_HACK;
}
- SURFACE_UnlockSurface(psurfBmp);
+ /* Mark as API bitmap */
+ psurf->flags |= (flags | API_BITMAP);
- DPRINT("IntGdiCreateBitmap : %dx%d, %d BPP colors, topdown %d, returning %08x\n",
- Size.cx, Size.cy, BitsPixel, (Height < 0 ? 1 : 0), hBitmap);
+ /* Set the bitmap bits */
+ if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
+ {
+ /* Bail out if that failed */
+ DPRINT1("SURFACE_bSetBitmapBits failed.\n");
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ return NULL;
+ }
- return hBitmap;
+ /* Unlock the surface and return */
+ SURFACE_UnlockSurface(psurf);
+ return hbmp;
}
+/* Creates a DDB surface,
+ * as in CreateCompatibleBitmap or CreateBitmap.
+ */
+HBITMAP
+APIENTRY
+GreCreateBitmap(
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
+ IN OPTIONAL PVOID pvBits)
+{
+ /* Call the extended function */
+ return GreCreateBitmapEx(nWidth,
+ nHeight,
+ 0, /* auto width */
+ BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
+ 0, /* no bitmap flags */
+ 0, /* auto size */
+ pvBits,
+ DDB_SURFACE /* DDB */);
+}
-HBITMAP APIENTRY
+HBITMAP
+APIENTRY
NtGdiCreateBitmap(
- INT Width,
- INT Height,
- UINT Planes,
- UINT BitsPixel,
+ IN INT nWidth,
+ IN INT nHeight,
+ IN UINT cPlanes,
+ IN UINT cBitsPixel,
IN OPTIONAL LPBYTE pUnsafeBits)
{
- if (pUnsafeBits)
+ HBITMAP hbmp;
+ ULONG cjWidthBytes, iFormat;
+
+ /* NOTE: Windows also doesn't store nr. of planes separately! */
+ cBitsPixel = BITMAP_GetRealBitsPixel(cBitsPixel * cPlanes);
+
+ /* Calculate bitmap format */
+ iFormat = BitmapFormat(cBitsPixel, BI_RGB);
+
+ /* Check parameters */
+ if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0)
{
- BOOL Hit = FALSE;
- UINT cjBits = BITMAP_GetWidthBytes(Width, BitsPixel) * abs(Height);
+ DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
+ nWidth, nHeight, cBitsPixel);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
- // FIXME: Use MmSecureVirtualMemory
+ /* Make sure that cjBits will not overflow */
+ cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
+ if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL)
+ {
+ DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
+ nWidth, nHeight, cBitsPixel);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ /* cBitsPixel = cBitsPixel * cPlanes now! */
+ hbmp = GreCreateBitmap(nWidth, nHeight, 1, cBitsPixel, NULL);
+
+ if (pUnsafeBits)
+ {
+ PSURFACE psurf = SURFACE_LockSurface(hbmp);
_SEH2_TRY
{
- ProbeForRead(pUnsafeBits, cjBits, 1);
+ ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1);
+ UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Hit = TRUE;
+ SURFACE_UnlockSurface(psurf);
+ SURFACE_FreeSurfaceByHandle(hbmp);
+ _SEH2_YIELD(return NULL;)
}
_SEH2_END
- if (Hit) return 0;
+ SURFACE_UnlockSurface(psurf);
}
- return IntGdiCreateBitmap(Width, Height, Planes, BitsPixel, pUnsafeBits);
+ return hbmp;
}
+
HBITMAP FASTCALL
IntCreateCompatibleBitmap(
PDC Dc,
{
if (Dc->dctype != DC_TYPE_MEMORY)
{
- Bmp = IntGdiCreateBitmap(abs(Width),
- abs(Height),
- IntGdiGetDeviceCaps(Dc,PLANES),
- IntGdiGetDeviceCaps(Dc,BITSPIXEL),
- NULL);
+ PSURFACE psurf;
+
+ Bmp = GreCreateBitmap(abs(Width),
+ abs(Height),
+ 1,
+ Dc->ppdev->gdiinfo.cBitsPixel,
+ NULL);
+ psurf = SURFACE_LockSurface(Bmp);
+ ASSERT(psurf);
+ /* Set palette */
+ psurf->ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
+ /* Set flags */
+ psurf->flags = API_BITMAP;
+ psurf->hdc = NULL; // Fixme
+ SURFACE_UnlockSurface(psurf);
}
else
{
{
if (Count == sizeof(BITMAP))
{
- /* We have a bitmap bug!!! W/O the HACK, we have white icons.
-
- MSDN Note: When a memory device context is created, it initially
- has a 1-by-1 monochrome bitmap selected into it. If this memory
- device context is used in CreateCompatibleBitmap, the bitmap that
- is created is a monochrome bitmap. To create a color bitmap, use
- the hDC that was used to create the memory device context, as
- shown in the following code:
-
- HDC memDC = CreateCompatibleDC(hDC);
- HBITMAP memBM = CreateCompatibleBitmap(hDC, nWidth, nHeight);
- SelectObject(memDC, memBM);
- */
- Bmp = IntGdiCreateBitmap(abs(Width),
- abs(Height),
- dibs.dsBm.bmPlanes,
- IntGdiGetDeviceCaps(Dc,BITSPIXEL),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
- NULL);
+ PSURFACE psurfBmp;
+
+ Bmp = GreCreateBitmap(abs(Width),
+ abs(Height),
+ 1,
+ dibs.dsBm.bmBitsPixel,
+ NULL);
+ psurfBmp = SURFACE_LockSurface(Bmp);
+ ASSERT(psurfBmp);
+ /* Assign palette */
+ psurfBmp->ppal = psurf->ppal;
+ GDIOBJ_IncrementShareCount((POBJ)psurf->ppal);
+ /* Set flags */
+ psurfBmp->flags = API_BITMAP;
+ psurfBmp->hdc = NULL; // Fixme
+ SURFACE_UnlockSurface(psurfBmp);
}
else
{
/* A DIB section is selected in the DC */
- BITMAPINFO *bi;
+ BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
PVOID Bits;
-
- /* Allocate memory for a BITMAPINFOHEADER structure and a
- color table. The maximum number of colors in a color table
- is 256 which corresponds to a bitmap with depth 8.
- Bitmaps with higher depths don't have color tables. */
- bi = ExAllocatePoolWithTag(PagedPool,
- sizeof(BITMAPINFOHEADER) +
- 256 * sizeof(RGBQUAD),
- TAG_TEMP);
-
- if (bi)
+ BITMAPINFO* bi = (BITMAPINFO*)buf;
+
+ bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
+ bi->bmiHeader.biWidth = Width;
+ bi->bmiHeader.biHeight = Height;
+ bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
+ bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
+ bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
+ bi->bmiHeader.biSizeImage = 0;
+ bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
+ bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
+ bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
+ bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
+
+ if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ /* Copy the color masks */
+ RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
+ }
+ else if (bi->bmiHeader.biBitCount <= 8)
{
- bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
- bi->bmiHeader.biWidth = Width;
- bi->bmiHeader.biHeight = Height;
- bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
- bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
- bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
- bi->bmiHeader.biSizeImage = 0;
- bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
- bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
- bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
- bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
-
- if (bi->bmiHeader.biCompression == BI_BITFIELDS)
+ /* Copy the color table */
+ UINT Index;
+ PPALETTE PalGDI;
+
+ if (!psurf->ppal)
{
- /* Copy the color masks */
- RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3 * sizeof(DWORD));
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
}
- else if (bi->bmiHeader.biBitCount <= 8)
+
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
+ for (Index = 0;
+ Index < 256 && Index < PalGDI->NumColors;
+ Index++)
{
- /* Copy the color table */
- UINT Index;
- PPALETTE PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
-
- if (!PalGDI)
- {
- ExFreePoolWithTag(bi, TAG_TEMP);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- for (Index = 0;
- Index < 256 && Index < PalGDI->NumColors;
- Index++)
- {
- bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
- bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
- bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
- bi->bmiColors[Index].rgbReserved = 0;
- }
- PALETTE_UnlockPalette(PalGDI);
+ bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
+ bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
+ bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
+ bi->bmiColors[Index].rgbReserved = 0;
}
+ PALETTE_UnlockPalette(PalGDI);
Bmp = DIB_CreateDIBSection(Dc,
bi,
NULL,
0,
0);
-
- ExFreePoolWithTag(bi, TAG_TEMP);
return Bmp;
}
}
}
if (!hDC)
- return IntGdiCreateBitmap(Width, Height, 1, 1, 0);
+ return GreCreateBitmap(Width, Height, 1, 1, 0);
Dc = DC_LockDc(hDC);
_SEH2_TRY
{
ProbeForWrite(Dimension, sizeof(SIZE), 1);
- *Dimension = psurfBmp->dimension;
+ *Dimension = psurfBmp->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
BOOL bInRect = FALSE;
SURFACE *psurf;
SURFOBJ *pso;
- HPALETTE hpal = 0;
- PPALETTE ppal;
EXLATEOBJ exlo;
HBITMAP hBmpTmp;
psurf = dc->dclevel.pSurface;
if (psurf)
{
- pso = &psurf->SurfObj;
- hpal = psurf->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
- ppal = PALETTE_ShareLockPalette(hpal);
-
- if (psurf->SurfObj.iBitmapFormat == BMF_1BPP && !psurf->hSecure)
- {
- /* FIXME: palette should be gpalMono already ! */
- EXLATEOBJ_vInitialize(&exlo, &gpalMono, &gpalRGB, 0, 0xffffff, 0);
- }
- else
- {
- EXLATEOBJ_vInitialize(&exlo, ppal, &gpalRGB, 0, 0xffffff, 0);
- }
-
+ pso = &psurf->SurfObj;
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, &gpalRGB, 0, 0xffffff, 0);
// check if this DC has a DIB behind it...
if (pso->pvScan0) // STYPE_BITMAP == pso->iType
{
}
EXLATEOBJ_vCleanup(&exlo);
- PALETTE_ShareUnlockPalette(ppal);
}
}
DC_UnlockDc(dc);
0,
0);
- //HBITMAP hBmpTmp = IntGdiCreateBitmap(1, 1, 1, 32, NULL);
+ //HBITMAP hBmpTmp = GreCreateBitmap(1, 1, 1, 32, NULL);
if (hBmpTmp)
{
HBITMAP hBmpOld = (HBITMAP)NtGdiSelectBitmap(hDCTmp, hBmpTmp);
return ret;
}
+VOID
+FASTCALL
+UnsafeGetBitmapBits(
+ PSURFACE psurf,
+ DWORD Bytes,
+ OUT PBYTE pvBits)
+{
+ PUCHAR pjDst, pjSrc;
+ LONG lDeltaDst, lDeltaSrc;
+ ULONG nWidth, nHeight, cBitsPixel;
+
+ nWidth = psurf->SurfObj.sizlBitmap.cx;
+ nHeight = psurf->SurfObj.sizlBitmap.cy;
+ cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+
+ /* Get pointers */
+ pjSrc = psurf->SurfObj.pvScan0;
+ pjDst = pvBits;
+ lDeltaSrc = psurf->SurfObj.lDelta;
+ lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
+
+ while (nHeight--)
+ {
+ /* Copy one line */
+ RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
+ pjSrc += lDeltaSrc;
+ pjDst += lDeltaDst;
+ }
+}
+
LONG APIENTRY
NtGdiGetBitmapBits(
HBITMAP hBitmap,
return 0;
}
- bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx,
+ bmSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx,
BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
abs(psurf->SurfObj.sizlBitmap.cy);
_SEH2_TRY
{
ProbeForWrite(pUnsafeBits, Bytes, 1);
- ret = IntGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ UnsafeGetBitmapBits(psurf, Bytes, pUnsafeBits);
+ ret = Bytes;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
-LONG APIENTRY
-IntSetBitmapBits(
- PSURFACE psurf,
- DWORD Bytes,
- IN PBYTE Bits)
-{
- LONG ret;
-
- /* Don't copy more bytes than the buffer has */
- Bytes = min(Bytes, psurf->SurfObj.cjBits);
-
-#if 0
- /* FIXME: call DDI specific function here if available */
- if (psurf->DDBitmap)
- {
- DPRINT("Calling device specific BitmapBits\n");
- if (psurf->DDBitmap->funcs->pBitmapBits)
- {
- ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap,
- (void *)Bits,
- Bytes,
- DDB_SET);
- }
- else
- {
- DPRINT("BitmapBits == NULL??\n");
- ret = 0;
- }
- }
- else
-#endif
- {
- RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes);
- ret = Bytes;
- }
-
- return ret;
-}
-
-
LONG APIENTRY
NtGdiSetBitmapBits(
HBITMAP hBitmap,
_SEH2_TRY
{
ProbeForRead(pUnsafeBits, Bytes, 1);
- ret = IntSetBitmapBits(psurf, Bytes, pUnsafeBits);
+ UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
+ ret = 1;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_TRY
{
ProbeForWrite(Size, sizeof(SIZE), 1);
- *Size = psurf->dimension;
+ *Size = psurf->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
}
/* The dimension is changed even if writing the old value failed */
- psurf->dimension.cx = Width;
- psurf->dimension.cy = Height;
+ psurf->sizlDim.cx = Width;
+ psurf->sizlDim.cy = Height;
SURFACE_UnlockSurface(psurf);
switch (*Color >> 24)
{
case 0x10: /* DIBINDEX */
- if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1)
+ if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1)
{
*Color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
}
default:
DPRINT("Unsupported color type %d passed\n", *Color >> 24);
break;
- }
+ }
}
BOOL APIENTRY
return 0;
}
-INT FASTCALL
-BITMAP_GetWidthBytes(INT bmWidth, INT bpp)
-{
-#if 0
- switch (bpp)
- {
- case 1:
- return 2 * ((bmWidth+15) >> 4);
-
- case 24:
- bmWidth *= 3; /* fall through */
- case 8:
- return bmWidth + (bmWidth & 1);
-
- case 32:
- return bmWidth * 4;
-
- case 16:
- case 15:
- return bmWidth * 2;
-
- case 4:
- return 2 * ((bmWidth+3) >> 2);
-
- default:
- DPRINT ("stub");
- }
-
- return -1;
-#endif
-
- return ((bmWidth * bpp + 15) & ~15) >> 3;
-}
-
HBITMAP FASTCALL
BITMAP_CopyBitmap(HBITMAP hBitmap)
{
return 0;
}
- Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP);
+ Bitmap = SURFACE_LockSurface(hBitmap);
if (Bitmap == NULL)
{
return 0;
Size.cx = abs(bm.bmWidth);
Size.cy = abs(bm.bmHeight);
- res = IntCreateBitmap(Size,
- bm.bmWidthBytes,
- BitmapFormat(bm.bmBitsPixel * bm.bmPlanes, BI_RGB),
- (bm.bmHeight < 0 ? BMF_TOPDOWN : 0) | BMF_NOZEROINIT,
- NULL);
+ res = GreCreateBitmapEx(Size.cx,
+ Size.cy,
+ bm.bmWidthBytes,
+ Bitmap->SurfObj.iBitmapFormat,
+ Bitmap->SurfObj.fjBitmap,
+ Bitmap->SurfObj.cjBits,
+ NULL,
+ Bitmap->flags);
+
if (res)
{
- PBYTE buf;
-
- resBitmap = GDIOBJ_LockObj(res, GDI_OBJECT_TYPE_BITMAP);
+ resBitmap = SURFACE_LockSurface(res);
if (resBitmap)
{
- buf = ExAllocatePoolWithTag(PagedPool,
- bm.bmWidthBytes * abs(bm.bmHeight),
- TAG_BITMAP);
- if (buf == NULL)
- {
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
- GreDeleteObject(res);
- return 0;
- }
- IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
- ExFreePoolWithTag(buf,TAG_BITMAP);
- resBitmap->flFlags = Bitmap->flFlags;
- GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
+ IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits);
+ SURFACE_UnlockSurface(resBitmap);
}
else
{
}
}
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
+ SURFACE_UnlockSurface(Bitmap);
return res;
}
pBitmap->bmType = 0;
pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
- pBitmap->bmWidthBytes = abs(psurf->SurfObj.lDelta);
pBitmap->bmPlanes = 1;
pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel);
/* Check for DIB section */
if (psurf->hSecure)
{
/* Set bmBits in this case */
pBitmap->bmBits = psurf->SurfObj.pvBits;
+ /* DIBs data are 32 bits aligned */
+ pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel);
if (Count >= sizeof(DIBSECTION))
{
pds->dsBmih.biHeight = pds->dsBm.bmHeight;
pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
- switch (psurf->SurfObj.iBitmapFormat)
- {
- /* FIXME: What about BI_BITFIELDS? */
- case BMF_1BPP:
- case BMF_4BPP:
- case BMF_8BPP:
- case BMF_16BPP:
- case BMF_24BPP:
- case BMF_32BPP:
- pds->dsBmih.biCompression = BI_RGB;
- break;
- case BMF_4RLE:
- pds->dsBmih.biCompression = BI_RLE4;
- break;
- case BMF_8RLE:
- pds->dsBmih.biCompression = BI_RLE8;
- break;
- case BMF_JPEG:
- pds->dsBmih.biCompression = BI_JPEG;
- break;
- case BMF_PNG:
- pds->dsBmih.biCompression = BI_PNG;
- break;
- }
+ if(psurf->ppal->flFlags & PAL_BITFIELDS)
+ {
+ pds->dsBmih.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ switch (psurf->SurfObj.iBitmapFormat)
+ {
+ case BMF_1BPP:
+ case BMF_4BPP:
+ case BMF_8BPP:
+ case BMF_16BPP:
+ case BMF_24BPP:
+ case BMF_32BPP:
+ pds->dsBmih.biCompression = BI_RGB;
+ break;
+ case BMF_4RLE:
+ pds->dsBmih.biCompression = BI_RLE4;
+ break;
+ case BMF_8RLE:
+ pds->dsBmih.biCompression = BI_RLE8;
+ break;
+ case BMF_JPEG:
+ pds->dsBmih.biCompression = BI_JPEG;
+ break;
+ case BMF_PNG:
+ pds->dsBmih.biCompression = BI_PNG;
+ break;
+ }
+ }
pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
pds->dsBmih.biXPelsPerMeter = 0;
pds->dsBmih.biYPelsPerMeter = 0;
- pds->dsBmih.biClrUsed = psurf->biClrUsed;
+ pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
pds->dsBmih.biClrImportant = psurf->biClrImportant;
- pds->dsBitfields[0] = psurf->dsBitfields[0];
- pds->dsBitfields[1] = psurf->dsBitfields[1];
- pds->dsBitfields[2] = psurf->dsBitfields[2];
+ pds->dsBitfields[0] = psurf->ppal->RedMask;
+ pds->dsBitfields[1] = psurf->ppal->GreenMask;
+ pds->dsBitfields[2] = psurf->ppal->BlueMask;
pds->dshSection = psurf->hDIBSection;
pds->dsOffset = psurf->dwOffset;
NtGdiGetDCforBitmap(
IN HBITMAP hsurf)
{
- HDC hDC = NULL;
+ HDC hdc = NULL;
PSURFACE psurf = SURFACE_LockSurface(hsurf);
if (psurf)
{
- hDC = psurf->hDC;
+ hdc = psurf->hdc;
SURFACE_UnlockSurface(psurf);
}
- return hDC;
+ return hdc;
}
+
/* EOF */
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS win32 subsystem
* PURPOSE: Functions for brushes
* FILE: subsystem/win32/win32k/objects/brush.c
- * PROGRAMER:
+ * PROGRAMER:
*/
#include <win32k.h>
DWORD nEntries;
PVOID AttrList[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST;
-
+
typedef struct _GDI_OBJ_ATTR_ENTRY
{
RGN_ATTR Attr[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
-static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
+static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
{
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
{0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry;
int i;
-
+
pti = PsGetCurrentThreadWin32Thread();
if (pti->pgdiBrushAttr)
{
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
pti = PsGetCurrentThreadWin32Thread();
-
+
if (!pti) return;
-
+
if (!pti->pgdiBrushAttr)
{ // If it is null, just cache it for the next time.
pti->pgdiBrushAttr = pAttr;
return sizeof(LOGBRUSH);
}
-/**
- * @name CalculateColorTableSize
- *
- * Internal routine to calculate the number of color table entries.
- *
- * @param BitmapInfoHeader
- * Input bitmap information header, can be any version of
- * BITMAPINFOHEADER or BITMAPCOREHEADER.
- *
- * @param ColorSpec
- * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS
- * or DIB_RGB_COLORS). On successful return this value is normalized
- * according to the bitmap info.
- *
- * @param ColorTableSize
- * On successful return this variable is filled with number of
- * entries in color table for the image with specified parameters.
- *
- * @return
- * TRUE if the input values together form a valid image, FALSE otherwise.
- */
-BOOL
-APIENTRY
-CalculateColorTableSize(
- CONST BITMAPINFOHEADER *BitmapInfoHeader,
- UINT *ColorSpec,
- UINT *ColorTableSize)
-{
- WORD BitCount;
- DWORD ClrUsed;
- DWORD Compression;
-
- /*
- * At first get some basic parameters from the passed BitmapInfoHeader
- * structure. It can have one of the following formats:
- * - BITMAPCOREHEADER (the oldest one with totally different layout
- * from the others)
- * - BITMAPINFOHEADER (the standard and most common header)
- * - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
- * - BITMAPV5HEADER (extension of BITMAPV4HEADER)
- */
- if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
- {
- BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount;
- ClrUsed = 0;
- Compression = BI_RGB;
- }
- else
- {
- BitCount = BitmapInfoHeader->biBitCount;
- ClrUsed = BitmapInfoHeader->biClrUsed;
- Compression = BitmapInfoHeader->biCompression;
- }
-
- switch (Compression)
- {
- case BI_BITFIELDS:
- if (*ColorSpec == DIB_PAL_COLORS)
- *ColorSpec = DIB_RGB_COLORS;
-
- if (BitCount != 16 && BitCount != 32)
- return FALSE;
-
- /* For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
- * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
- * For BITMAPINFOHEADER the color masks are stored in the palette. */
- if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER))
- *ColorTableSize = 0;
- else
- *ColorTableSize = 3;
-
- return TRUE;
-
- case BI_RGB:
- switch (BitCount)
- {
- case 1:
- *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2;
- return TRUE;
-
- case 4:
- *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
- return TRUE;
-
- case 8:
- *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
- return TRUE;
-
- default:
- if (*ColorSpec == DIB_PAL_COLORS)
- *ColorSpec = DIB_RGB_COLORS;
- if (BitCount != 16 && BitCount != 24 && BitCount != 32)
- return FALSE;
- *ColorTableSize = ClrUsed;
- return TRUE;
- }
-
- case BI_RLE4:
- if (BitCount == 4)
- {
- *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
- return TRUE;
- }
- return FALSE;
-
- case BI_RLE8:
- if (BitCount == 8)
- {
- *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
- return TRUE;
- }
- return FALSE;
-
- case BI_JPEG:
- case BI_PNG:
- *ColorTableSize = ClrUsed;
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
HBRUSH
APIENTRY
IntGdiCreateDIBBrush(
PBRUSH pbrush;
HBITMAP hPattern;
ULONG_PTR DataPtr;
- UINT PaletteEntryCount;
- PSURFACE psurfPattern;
- INT PaletteType;
+ PVOID pvDIBits;
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
{
return NULL;
}
- if (!CalculateColorTableSize(&BitmapInfo->bmiHeader,
- &ColorSpec,
- &PaletteEntryCount))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- // FIXME: What about BI_BITFIELDS
- DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize;
- if (ColorSpec == DIB_RGB_COLORS)
- DataPtr += PaletteEntryCount * sizeof(RGBQUAD);
- else
- DataPtr += PaletteEntryCount * sizeof(USHORT);
+ DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
- hPattern = IntGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth,
- BitmapInfo->bmiHeader.biHeight,
- BitmapInfo->bmiHeader.biPlanes,
- BitmapInfo->bmiHeader.biBitCount,
- (PVOID)DataPtr);
+ hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0);
if (hPattern == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
-
- psurfPattern = SURFACE_LockSurface(hPattern);
- ASSERT(psurfPattern != NULL);
- psurfPattern->hDIBPalette = BuildDIBPalette(BitmapInfo, &PaletteType);
- SURFACE_UnlockSurface(psurfPattern);
+ RtlCopyMemory(pvDIBits,
+ (PVOID)DataPtr,
+ DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth,
+ BitmapInfo->bmiHeader.biHeight,
+ BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes));
pbrush = BRUSH_AllocBrushWithHandle();
if (pbrush == NULL)
return 0;
}
- hPattern = IntGdiCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
+ hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
if (hPattern == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
PROSRGNDATA CombinedRegion;
HRGN hRgnVis = Dc->prgnVis->BaseObject.hHmgr;
- /* Experiment with API region based on wine.. */
- if (Dc->rosdc.hClipRgn && Dc->dclevel.prgnMeta)
+ // would prefer this, but the rest of the code sucks
+// ASSERT(Dc->rosdc.hGCClipRgn);
+// ASSERT(Dc->rosdc.hClipRgn);
+ if (!Dc->prgnVis)
{
- PROSRGNDATA pClipRgn;
-
- if ((pClipRgn = RGNOBJAPI_Lock(Dc->rosdc.hClipRgn, NULL)))
- {
- if (!Dc->prgnAPI) Dc->prgnAPI = IntSysCreateRectpRgn( 0, 0, 0, 0 );
-
- IntGdiCombineRgn( Dc->prgnAPI,
- pClipRgn,
- Dc->dclevel.prgnMeta,
- RGN_AND );
- RGNOBJAPI_Unlock(pClipRgn);
- }
+ DPRINT1("Warning, prgnVis is NULL!\n");
}
else
{
- if (Dc->prgnAPI)
- GreDeleteObject(((PROSRGNDATA)Dc->prgnAPI)->BaseObject.hHmgr);
- Dc->prgnAPI = NULL;
+ hRgnVis = Dc->prgnVis->BaseObject.hHmgr ;
}
NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y);
- if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
- {
- CLIPOBJ *CombinedClip;
-
- CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
- CombinedRegion->Buffer,
- &CombinedRegion->rdh.rcBound);
+ if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL)))
+ {
+ CLIPOBJ *CombinedClip;
- RGNOBJAPI_Unlock(CombinedRegion);
+ CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount,
+ CombinedRegion->Buffer,
+ &CombinedRegion->rdh.rcBound);
- if (!CombinedClip)
- {
- DPRINT1("IntEngCreateClipRegion() failed\n");
- return ERROR;
- }
+ RGNOBJAPI_Unlock(CombinedRegion);
- if (Dc->rosdc.CombinedClip != NULL)
- IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
+ if ( !CombinedClip )
+ {
+ DPRINT1("IntEngCreateClipRegion() failed\n");
+ return ERROR;
+ }
- Dc->rosdc.CombinedClip = CombinedClip;
- }
+ if(Dc->rosdc.CombinedClip != NULL)
+ IntEngDeleteClipRegion(Dc->rosdc.CombinedClip);
+ Dc->rosdc.CombinedClip = CombinedClip ;
+ }
return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y);
}
NtGdiOffsetRgn(dc->prgnVis->BaseObject.hHmgr, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
CLIPPING_UpdateGCRegion(dc);
}
-
DC_UnlockDc(dc);
return retval;
else
NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode);
}
+
return CLIPPING_UpdateGCRegion(dc);
}
retval = REGION_GetRgnBox(pRgnNew, rc);
REGION_FreeRgnByHandle(pRgnNew->BaseObject.hHmgr);
+
DC_UnlockDc(dc);
if(Unlock) REGION_UnlockRgn(pRgn);
return retval;
return Ret;
}
+
int APIENTRY NtGdiSetMetaRgn(HDC hDC)
{
INT Ret;
IntGdiCombineRgn( pDC->prgnAPI,
pDC->dclevel.prgnClip,
pDC->dclevel.prgnMeta,
- RGN_AND );
+ RGN_AND);
}
else
{
IntGdiCombineRgn( pDC->prgnAPI,
pDC->dclevel.prgnClip,
NULL,
- RGN_COPY );
+ RGN_COPY);
}
else if (pDC->dclevel.prgnMeta)
{
IntGdiCombineRgn( pDC->prgnAPI,
pDC->dclevel.prgnMeta,
NULL,
- RGN_COPY );
+ RGN_COPY);
}
}
IntGdiCombineRgn( pDC->prgnRao,
pDC->prgnVis,
pDC->prgnAPI,
- RGN_AND );
+ RGN_AND);
- RtlCopyMemory( &pDC->erclClip,
- &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound,
- sizeof(RECTL));
+ RtlCopyMemory(&pDC->erclClip,
+ &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound,
+ sizeof(RECTL));
pDC->fs &= ~DC_FLAG_DIRTY_RAO;
IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
// pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
- // the rects from region objects rects in pClipRgn->Buffer.
+ // the rects from region objects rects in pClipRgn->Buffer.
// With pDC->co.pClipRgn->Buffer,
// pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis;
co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount,
((PROSRGNDATA)pDC->prgnRao)->Buffer,
- &pDC->erclClip);
-
+ &pDC->erclClip);
if (co)
{
if (pDC->rosdc.CombinedClip != NULL)
- IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
+ IntEngDeleteClipRegion(pDC->rosdc.CombinedClip);
pDC->rosdc.CombinedClip = co;
}
return;
}
+BOOL
+FASTCALL
+DC_AllocDcAttr(PDC pdc)
+{
+ DC_AllocateDcAttr(pdc->BaseObject.hHmgr);
+ *pdc->pdcattr = pdc->dcattr;
+ return TRUE;
+}
+
+// CHECK against current head
VOID
FASTCALL
DC_AllocateDcAttr(HDC hDC)
{
PVOID NewMem = NULL;
PDC pDC;
-
+ HANDLE Pid = NtCurrentProcess();
+ ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
+
+ NTSTATUS Status = ZwAllocateVirtualMemory(Pid,
+ &NewMem,
+ 0,
+ &MemSize,
+ MEM_COMMIT|MEM_RESERVE,
+ PAGE_READWRITE);
{
INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
-
- NewMem = AllocateDcAttr();
-
// FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData
-
- if (NewMem)
+ if (NT_SUCCESS(Status))
{
- RtlZeroMemory(NewMem, sizeof(DC_ATTR));
- Entry->UserData = NewMem;
- DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
+ RtlZeroMemory(NewMem, MemSize);
+ Entry->UserData = NewMem;
+ DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
}
else
{
- DPRINT1("DC_ATTR not allocated!\n");
+ DPRINT("DC_ATTR not allocated!\n");
}
}
pDC = DC_LockDc(hDC);
ASSERT(pDC->pdcattr == &pDC->dcattr);
- if (NewMem)
+ if(NewMem)
{
pDC->pdcattr = NewMem; // Store pointer
}
}
VOID
-FASTCALL
-DC_FreeDcAttr(HDC DCToFree )
+NTAPI
+DC_vFreeDcAttr(PDC pdc)
{
- PDC pDC = DC_LockDc(DCToFree);
- if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object!
- pDC->pdcattr = &pDC->dcattr;
- DC_UnlockDc(pDC);
+ HANDLE Pid = NtCurrentProcess();
+ INT Index;
+ PGDI_TABLE_ENTRY pent;
- {
- INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
- PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData)
+ if (pdc->pdcattr == &pdc->dcattr)
{
- FreeDcAttr(Entry->UserData);
- Entry->UserData = NULL;
+ // Internal DC object!
+ return;
+ }
+
+ pdc->pdcattr = &pdc->dcattr;
+
+ Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
+ pent = &GdiHandleTable->Entries[Index];
+ if(pent->UserData)
+ {
+ ULONG MemSize = sizeof(DC_ATTR);
+ NTSTATUS Status = ZwFreeVirtualMemory(Pid,
+ &pent->UserData,
+ &MemSize,
+ MEM_RELEASE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("DC_FreeDC failed to free DC_ATTR 0x%p\n", pent->UserData);
+ ASSERT(FALSE);
+ }
+ pent->UserData = NULL;
}
- }
}
_SEH2_TRY
{
- ProbeForWrite( pdcattr,
- sizeof(DC_ATTR),
- 1);
- RtlCopyMemory( pdcattr,
- &dc->dcattr,
- sizeof(DC_ATTR));
+ ProbeForWrite(pdcattr, sizeof(DC_ATTR), 1);
+ RtlCopyMemory(pdcattr, &dc->dcattr, sizeof(DC_ATTR));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
#define NDEBUG
#include <debug.h>
-/** Internal functions ********************************************************/
+//FIXME: windows uses 0x0012009f
+#define DIRTY_DEFAULT DIRTY_CHARSET|DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL
-HDC FASTCALL
-DC_AllocDC(PUNICODE_STRING Driver)
-{
- PDC NewDC;
- PDC_ATTR pdcattr;
- HDC hDC;
- PWSTR Buf = NULL;
- XFORM xformTemplate;
- PBRUSH pbrush;
- HSURF hsurf;
-
- if (Driver != NULL)
- {
- Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
- if (!Buf)
- {
- DPRINT1("ExAllocatePoolWithTag failed\n");
- return NULL;
- }
- RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
- }
+PSURFACE psurfDefaultBitmap = NULL;
+PBRUSH pbrDefaultBrush = NULL;
- NewDC = (PDC)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DC);
- if (!NewDC)
- {
- if (Buf)
- {
- ExFreePoolWithTag(Buf, TAG_DC);
- }
- DPRINT1("GDIOBJ_AllocObjWithHandle failed\n");
- return NULL;
- }
+// FIXME: these should go to floatobj.h or something
+#define FLOATOBJ_0 {0x00000000, 0x00000000}
+#define FLOATOBJ_1 {0x40000000, 0x00000002}
+#define FLOATOBJ_16 {0x40000000, 0x00000006}
+#define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
- hDC = NewDC->BaseObject.hHmgr;
+static const FLOATOBJ gef0 = FLOATOBJ_0;
+static const FLOATOBJ gef1 = FLOATOBJ_1;
+static const FLOATOBJ gef16 = FLOATOBJ_16;
- NewDC->pdcattr = &NewDC->dcattr;
- DC_AllocateDcAttr(hDC);
+static const MATRIX gmxWorldToDeviceDefault =
+{
+ FLOATOBJ_16, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_16,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x4b
+};
- if (Driver != NULL)
- {
- RtlCopyMemory(&NewDC->rosdc.DriverName, Driver, sizeof(UNICODE_STRING));
- NewDC->rosdc.DriverName.Buffer = Buf;
- }
- pdcattr = NewDC->pdcattr;
+static const MATRIX gmxDeviceToWorldDefault =
+{
+ FLOATOBJ_1_16, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_1_16,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x53
+};
- // FIXME: no floating point in the kernel!
- xformTemplate.eM11 = 1.0f;
- xformTemplate.eM12 = 0.0f;
- xformTemplate.eM21 = 0.0f;
- xformTemplate.eM22 = 1.0f;
- xformTemplate.eDx = 0.0f;
- xformTemplate.eDy = 0.0f;
- XForm2MatrixS(&NewDC->dclevel.mxWorldToDevice, &xformTemplate);
- XForm2MatrixS(&NewDC->dclevel.mxDeviceToWorld, &xformTemplate);
- XForm2MatrixS(&NewDC->dclevel.mxWorldToPage, &xformTemplate);
+static const MATRIX gmxWorldToPageDefault =
+{
+ FLOATOBJ_1, FLOATOBJ_0,
+ FLOATOBJ_0, FLOATOBJ_1,
+ FLOATOBJ_0, FLOATOBJ_0,
+ 0, 0, 0x63
+};
- // Setup syncing bits for the dcattr data packets.
- pdcattr->flXform = DEVICE_TO_PAGE_INVALID;
+// HACK!! Fix XFORMOBJ then use 1:16 / 16:1
+#define gmxWorldToDeviceDefault gmxWorldToPageDefault
+#define gmxDeviceToWorldDefault gmxWorldToPageDefault
- pdcattr->ulDirty_ = 0; // Server side
+/** Internal functions ********************************************************/
- pdcattr->iMapMode = MM_TEXT;
- pdcattr->iGraphicsMode = GM_COMPATIBLE;
- pdcattr->jFillMode = ALTERNATE;
+NTSTATUS
+InitDcImpl()
+{
+ psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
+ if (!psurfDefaultBitmap)
+ return STATUS_UNSUCCESSFUL;
- pdcattr->szlWindowExt.cx = 1; // Float to Int,,, WRONG!
- pdcattr->szlWindowExt.cy = 1;
- pdcattr->szlViewportExt.cx = 1;
- pdcattr->szlViewportExt.cy = 1;
+ pbrDefaultBrush = BRUSH_ShareLockBrush(StockObjects[BLACK_BRUSH]);
+ if (!pbrDefaultBrush)
+ return STATUS_UNSUCCESSFUL;
- pdcattr->crForegroundClr = 0;
- pdcattr->ulForegroundClr = 0;
+ return STATUS_SUCCESS;
+}
- pdcattr->ulBackgroundClr = 0xffffff;
- pdcattr->crBackgroundClr = 0xffffff;
- pdcattr->ulPenClr = RGB(0, 0, 0);
- pdcattr->crPenClr = RGB(0, 0, 0);
+PDC
+NTAPI
+DC_AllocDcWithHandle()
+{
+ PDC pdc;
+ pdc = (PDC)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_DC_TYPE);
- pdcattr->ulBrushClr = RGB(255, 255, 255); // Do this way too.
- pdcattr->crBrushClr = RGB(255, 255, 255);
+ pdc->pdcattr = &pdc->dcattr;
-//// This fixes the default brush and pen settings. See DC_InitDC.
+ return pdc;
+}
- /* Create the default fill brush */
- pdcattr->hbrush = NtGdiGetStockObject(WHITE_BRUSH);
- NewDC->dclevel.pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush);
- EBRUSHOBJ_vInit(&NewDC->eboFill, NewDC->dclevel.pbrFill, NewDC);
- /* Create the default pen / line brush */
- pdcattr->hpen = NtGdiGetStockObject(BLACK_PEN);
- NewDC->dclevel.pbrLine = PEN_ShareLockPen(pdcattr->hpen);
- EBRUSHOBJ_vInit(&NewDC->eboLine, NewDC->dclevel.pbrLine, NewDC);
+void
+DC_InitHack(PDC pdc)
+{
+ TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
+ pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
- /* Create the default text brush */
- pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(BLACK_BRUSH));
- EBRUSHOBJ_vInit(&NewDC->eboText, pbrush, NewDC);
- pdcattr->ulDirty_ |= DIRTY_TEXT;
+ /* This should never fail */
+ ASSERT(pdc->dclevel.ppal);
- /* Create the default background brush */
- pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(WHITE_BRUSH));
- EBRUSHOBJ_vInit(&NewDC->eboBackground, pbrush, NewDC);
+ /* Select regions */
+ pdc->rosdc.hClipRgn = NULL;
+ pdc->rosdc.hGCClipRgn = NULL;
+}
- pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
- TextIntRealizeFont(pdcattr->hlfntNew,NULL);
- NewDC->hlfntCur = pdcattr->hlfntNew;
- NewDC->dclevel.plfnt = GDIOBJ_GetKernelObj(pdcattr->hlfntNew);
+VOID
+NTAPI
+DC_vInitDc(
+ PDC pdc,
+ DCTYPE dctype,
+ PPDEVOBJ ppdev)
+{
+ /* Setup some basic fields */
+ pdc->dctype = dctype;
+ pdc->ppdev = ppdev;
+ pdc->dhpdev = ppdev->dhpdev;
+ pdc->hsem = ppdev->hsemDevLock;
+ pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
+ pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
+ pdc->fs = DC_DIRTY_RAO;
+
+ /* Setup dc attribute */
+ pdc->pdcattr = &pdc->dcattr;
+ pdc->dcattr.pvLDC = NULL;
+ pdc->dcattr.ulDirty_ = DIRTY_DEFAULT;
+ if (ppdev == gppdevPrimary)
+ pdc->dcattr.ulDirty_ |= DC_PRIMARY_DISPLAY;
+
+ /* Setup the DC size */
+ if (dctype == DCTYPE_MEMORY)
+ {
+ /* Memory DCs have a 1 x 1 bitmap by default */
+ pdc->dclevel.sizl.cx = 1;
+ pdc->dclevel.sizl.cy = 1;
+ }
+ else
+ {
+ /* Other DC's are as big as the related PDEV */
+ pdc->dclevel.sizl.cx = ppdev->gdiinfo.ulHorzRes;
+ pdc->dclevel.sizl.cy = ppdev->gdiinfo.ulVertRes;
+ }
- NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
- NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal);
- /* This should never fail */
- ASSERT(NewDC->dclevel.ppal);
+ /* Setup Window rect based on DC size */
+ pdc->erclWindow.left = 0;
+ pdc->erclWindow.top = 0;
+ pdc->erclWindow.right = pdc->dclevel.sizl.cx;
+ pdc->erclWindow.bottom = pdc->dclevel.sizl.cy;
- NewDC->dclevel.laPath.eMiterLimit = 10.0; // FIXME: use FLOATL or FLOATOBJ!
+ if (dctype == DCTYPE_DIRECT)
+ {
+ /* Direct DCs get the surface from the PDEV */
+ pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
+
+ pdc->erclBounds.left = 0x7fffffff;
+ pdc->erclBounds.top = 0x7fffffff;
+ pdc->erclBounds.right = 0x80000000;
+ pdc->erclBounds.bottom = 0x80000000;
+ pdc->erclBoundsApp.left = 0xffffffff;
+ pdc->erclBoundsApp.top = 0xfffffffc;
+ pdc->erclBoundsApp.right = 0x00007ffc; // FIXME
+ pdc->erclBoundsApp.bottom = 0x00000333; // FIXME
+ pdc->erclClip = pdc->erclBounds;
+// pdc->co
+
+ pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY;
+ }
+ else
+ {
+ /* Non-direct DCs don't have a surface by default */
+ pdc->dclevel.pSurface = NULL;
- NewDC->dclevel.lSaveDepth = 1;
+ // FIXME: HACK, because our code expects a surface
+ pdc->dclevel.pSurface = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]);
- hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that?
- NewDC->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
+ pdc->erclBounds.left = 0;
+ pdc->erclBounds.top = 0;
+ pdc->erclBounds.right = 0;
+ pdc->erclBounds.bottom = 0;
+ pdc->erclBoundsApp = pdc->erclBounds;
+ pdc->erclClip = pdc->erclWindow;
+// pdc->co = NULL
+ }
+// pdc->dcattr.VisRectRegion:
+
+ /* Setup coordinate transformation data */
+ pdc->dclevel.mxWorldToDevice = gmxWorldToDeviceDefault;
+ pdc->dclevel.mxDeviceToWorld = gmxDeviceToWorldDefault;
+ pdc->dclevel.mxWorldToPage = gmxWorldToPageDefault;
+ pdc->dclevel.efM11PtoD = gef16;
+ pdc->dclevel.efM22PtoD = gef16;
+ pdc->dclevel.efDxPtoD = gef0;
+ pdc->dclevel.efDyPtoD = gef0;
+ pdc->dclevel.efM11_TWIPS = gef0;
+ pdc->dclevel.efM22_TWIPS = gef0;
+ pdc->dclevel.efPr11 = gef0;
+ pdc->dclevel.efPr22 = gef0;
+ pdc->dcattr.mxWorldToDevice = pdc->dclevel.mxWorldToDevice;
+ pdc->dcattr.mxDeviceToWorld = pdc->dclevel.mxDeviceToWorld;
+ pdc->dcattr.mxWorldToPage = pdc->dclevel.mxWorldToPage;
+ pdc->dcattr.efM11PtoD = pdc->dclevel.efM11PtoD;
+ pdc->dcattr.efM22PtoD = pdc->dclevel.efM22PtoD;
+ pdc->dcattr.efDxPtoD = pdc->dclevel.efDxPtoD;
+ pdc->dcattr.efDyPtoD = pdc->dclevel.efDyPtoD;
+ pdc->dcattr.iMapMode = MM_TEXT;
+ pdc->dcattr.dwLayout = 0;
+ pdc->dcattr.flXform = PAGE_TO_DEVICE_SCALE_IDENTITY |
+ PAGE_TO_DEVICE_IDENTITY |
+ WORLD_TO_PAGE_IDENTITY;
+
+ /* Setup more coordinates */
+ pdc->ptlDCOrig.x = 0;
+ pdc->ptlDCOrig.y = 0;
+ pdc->dcattr.lWindowOrgx = 0;
+ pdc->dcattr.ptlWindowOrg.x = 0;
+ pdc->dcattr.ptlWindowOrg.y = 0;
+ pdc->dcattr.szlWindowExt.cx = 1;
+ pdc->dcattr.szlWindowExt.cy = 1;
+ pdc->dcattr.ptlViewportOrg.x = 0;
+ pdc->dcattr.ptlViewportOrg.y = 0;
+ pdc->dcattr.szlViewportExt.cx = 1;
+ pdc->dcattr.szlViewportExt.cy = 1;
+ pdc->dcattr.szlVirtualDevicePixel.cx = ppdev->gdiinfo.ulHorzRes;
+ pdc->dcattr.szlVirtualDevicePixel.cy = ppdev->gdiinfo.ulVertRes;
+ pdc->dcattr.szlVirtualDeviceMm.cx = ppdev->gdiinfo.ulHorzSize;
+ pdc->dcattr.szlVirtualDeviceMm.cy = ppdev->gdiinfo.ulVertSize;
+ pdc->dcattr.szlVirtualDeviceSize.cx = 0;
+ pdc->dcattr.szlVirtualDeviceSize.cy = 0;
+
+ /* Setup regions */
+ pdc->prgnAPI = NULL;
+ pdc->prgnRao = NULL;
/* Allocate a Vis region */
- NewDC->prgnVis = IntSysCreateRectpRgn(0, 0, 1, 1);
- if (!NewDC->prgnVis)
- {
- DPRINT1("IntSysCreateRectpRgn failed\n");
- if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC))
- {
- ASSERT(FALSE);
- }
- return NULL;
- }
+ pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+ ASSERT(pdc->prgnVis);
+ GDIOBJ_CopyOwnership(pdc->BaseObject.hHmgr, pdc->prgnVis->BaseObject.hHmgr);
+
+ /* Setup palette */
+ pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE];
+ pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
+
+ /* Setup path */
+ pdc->dclevel.hPath = NULL;
+ pdc->dclevel.flPath = 0;
+// pdc->dclevel.lapath:
+
+ /* Setup colors */
+ pdc->dcattr.crBackgroundClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.ulBackgroundClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.crForegroundClr = RGB(0, 0, 0);
+ pdc->dcattr.ulForegroundClr = RGB(0, 0, 0);
+ pdc->dcattr.crBrushClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.ulBrushClr = RGB(0xff, 0xff, 0xff);
+ pdc->dcattr.crPenClr = RGB(0, 0, 0);
+ pdc->dcattr.ulPenClr = RGB(0, 0, 0);
+
+ /* Select the default fill and line brush */
+ pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH];
+ pdc->dcattr.hpen = StockObjects[BLACK_PEN];
+ pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush);
+ pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen);
+ pdc->dclevel.ptlBrushOrigin.x = 0;
+ pdc->dclevel.ptlBrushOrigin.y = 0;
+ pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin;
+
+ /* Initialize EBRUSHOBJs */
+ EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc);
+ EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc);
+
+ /* Setup fill data */
+ pdc->dcattr.jROP2 = R2_COPYPEN;
+ pdc->dcattr.jBkMode = 2;
+ pdc->dcattr.lBkMode = 2;
+ pdc->dcattr.jFillMode = ALTERNATE;
+ pdc->dcattr.lFillMode = 1;
+ pdc->dcattr.jStretchBltMode = 1;
+ pdc->dcattr.lStretchBltMode = 1;
+ pdc->ptlFillOrigin.x = 0;
+ pdc->ptlFillOrigin.y = 0;
+
+ /* Setup drawing position */
+ pdc->dcattr.ptlCurrent.x = 0;
+ pdc->dcattr.ptlCurrent.y = 0;
+ pdc->dcattr.ptfxCurrent.x = 0;
+ pdc->dcattr.ptfxCurrent.y = 0;
+
+ /* Setup ICM data */
+ pdc->dclevel.lIcmMode = 0;
+ pdc->dcattr.lIcmMode = 0;
+ pdc->dcattr.hcmXform = NULL;
+ pdc->dcattr.flIcmFlags = 0;
+ pdc->dcattr.IcmBrushColor = CLR_INVALID;
+ pdc->dcattr.IcmPenColor = CLR_INVALID;
+ pdc->dcattr.pvLIcm = NULL;
+ pdc->dcattr.hColorSpace = NULL; // FIXME: 0189001f
+ pdc->dclevel.pColorSpace = NULL; // FIXME
+ pdc->pClrxFormLnk = NULL;
+// pdc->dclevel.ca =
+
+ /* Setup font data */
+ pdc->hlfntCur = NULL; // FIXME: 2f0a0cf8
+ pdc->pPFFList = NULL;
+ pdc->flSimulationFlags = 0;
+ pdc->lEscapement = 0;
+ pdc->prfnt = NULL;
+ pdc->dcattr.flFontMapper = 0;
+ pdc->dcattr.flTextAlign = 0;
+ pdc->dcattr.lTextAlign = 0;
+ pdc->dcattr.lTextExtra = 0;
+ pdc->dcattr.lRelAbs = 1;
+ pdc->dcattr.lBreakExtra = 0;
+ pdc->dcattr.cBreak = 0;
+ pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT];
+// pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew);
+
+ /* Other stuff */
+ pdc->hdcNext = NULL;
+ pdc->hdcPrev = NULL;
+ pdc->ipfdDevMax = 0x0000ffff;
+ pdc->ulCopyCount = -1;
+ pdc->ptlDoBanding.x = 0;
+ pdc->ptlDoBanding.y = 0;
+ pdc->dclevel.lSaveDepth = 1;
+ pdc->dclevel.hdcSave = NULL;
+ pdc->dcattr.iGraphicsMode = GM_COMPATIBLE;
+ pdc->dcattr.iCS_CP = 0;
+ pdc->pSurfInfo = NULL;
- return NewDC;
}
-BOOL INTERNAL_CALL
+BOOL
+INTERNAL_CALL
DC_Cleanup(PVOID ObjectBody)
{
- PDC pDC = (PDC)ObjectBody;
+ PDC pdc = (PDC)ObjectBody;
- /* Free driver name (HACK) */
- if (pDC->rosdc.DriverName.Buffer)
- ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC);
+ /* Free DC_ATTR */
+ DC_vFreeDcAttr(pdc);
- /* Deselect dc objects */
- DC_vSelectSurface(pDC, NULL);
- DC_vSelectFillBrush(pDC, NULL);
- DC_vSelectLineBrush(pDC, NULL);
- DC_vSelectPalette(pDC, NULL);
+ /* Delete saved DCs */
+ DC_vRestoreDC(pdc, 1);
- /* Dereference default brushes */
- if (pDC->eboText.pbrush)
- BRUSH_ShareUnlockBrush(pDC->eboText.pbrush);
- if (pDC->eboBackground.pbrush)
- BRUSH_ShareUnlockBrush(pDC->eboBackground.pbrush);
+ /* Deselect dc objects */
+ DC_vSelectSurface(pdc, NULL);
+ DC_vSelectFillBrush(pdc, NULL);
+ DC_vSelectLineBrush(pdc, NULL);
+ DC_vSelectPalette(pdc, NULL);
/* Cleanup the dc brushes */
- EBRUSHOBJ_vCleanup(&pDC->eboFill);
- EBRUSHOBJ_vCleanup(&pDC->eboLine);
- EBRUSHOBJ_vCleanup(&pDC->eboText);
- EBRUSHOBJ_vCleanup(&pDC->eboBackground);
+ EBRUSHOBJ_vCleanup(&pdc->eboFill);
+ EBRUSHOBJ_vCleanup(&pdc->eboLine);
+ EBRUSHOBJ_vCleanup(&pdc->eboText);
+ EBRUSHOBJ_vCleanup(&pdc->eboBackground);
+
+ /* Free regions */
+ if (pdc->rosdc.hClipRgn)
+ GreDeleteObject(pdc->rosdc.hClipRgn);
+ if (pdc->prgnVis)
+ REGION_FreeRgnByHandle(pdc->prgnVis->BaseObject.hHmgr);
+ if (pdc->rosdc.hGCClipRgn)
+ GreDeleteObject(pdc->rosdc.hGCClipRgn);
+ if (NULL != pdc->rosdc.CombinedClip)
+ IntEngDeleteClipRegion(pdc->rosdc.CombinedClip);
+
+ PATH_Delete(pdc->dclevel.hPath);
+
+ if(pdc->dclevel.pSurface)
+ SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
+
+ PDEVOBJ_vRelease(pdc->ppdev) ;
return TRUE;
}
INT Index;
PGDI_TABLE_ENTRY Entry;
PDC pDC;
+ BOOL ret = FALSE;
+
+ if (!GDIOBJ_SetOwnership(hDC, Owner))
+ {
+ DPRINT1("GDIOBJ_SetOwnership failed\n");
+ return FALSE;
+ }
- if (!GDIOBJ_SetOwnership(hDC, Owner)) return FALSE;
pDC = DC_LockDc(hDC);
- if (pDC)
+ if (!pDC)
{
+ DPRINT1("Could not lock DC\n");
+ return FALSE;
+ }
+
/*
System Regions:
These regions do not use attribute sections and when allocated, use
gdiobj level functions.
*/
- if (pDC->rosdc.hClipRgn)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) return FALSE;
- }
- if (pDC->prgnVis)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) return FALSE;
- }
- if (pDC->rosdc.hGCClipRgn)
- { // FIXME! HAX!!!
- Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
- Entry = &GdiHandleTable->Entries[Index];
- if (Entry->UserData) FreeObjectAttr(Entry->UserData);
- Entry->UserData = NULL;
- //
- if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) return FALSE;
- }
- if (pDC->dclevel.hPath)
- {
- if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) return FALSE;
- }
- DC_UnlockDc(pDC);
+ if (pDC->rosdc.hClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) goto leave;
+ }
+ if (pDC->prgnVis)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) goto leave;
+ }
+ if (pDC->rosdc.hGCClipRgn)
+ { // FIXME! HAX!!!
+ Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ //
+ if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) goto leave;
+ }
+ if (pDC->dclevel.hPath)
+ {
+ if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) goto leave;
}
+ ret = TRUE;
- return TRUE;
+leave:
+ DC_UnlockDc(pDC);
+
+ return ret;
}
-HDC FASTCALL
-IntGdiCreateDC(
- PUNICODE_STRING Driver,
- PUNICODE_STRING Device,
- PVOID pUMdhpdev,
- CONST PDEVMODEW InitData,
- BOOL CreateAsIC)
+int FASTCALL
+CLIPPING_UpdateGCRegion(DC* Dc);
+
+static
+void
+DC_vUpdateDC(PDC pdc)
{
- HDC hdc;
- PDC pdc;
- PDC_ATTR pdcattr;
- HRGN hVisRgn;
- UNICODE_STRING StdDriver;
- BOOL calledFromUser;
+ HRGN hVisRgn ;
+ PPDEVOBJ ppdev = pdc->ppdev ;
+
+ pdc->dhpdev = ppdev->dhpdev;
- RtlInitUnicodeString(&StdDriver, L"DISPLAY");
+ SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface);
+ pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
- DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver, Device);
+ PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl);
+ hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
+ ASSERT(hVisRgn);
+ GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn);
+ GreDeleteObject(hVisRgn);
- if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE))
+ pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps;
+ pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2;
+
+ /* Mark EBRUSHOBJs as dirty */
+ pdc->pdcattr->ulDirty_ |= DIRTY_DEFAULT ;
+}
+
+/* Prepare a blit for up to 2 DCs */
+/* rc1 and rc2 are the rectangles where we want to draw or
+ * from where we take pixels. */
+VOID
+FASTCALL
+DC_vPrepareDCsForBlit(PDC pdc1,
+ RECT rc1,
+ PDC pdc2,
+ RECT rc2)
+{
+ PDC pdcFirst, pdcSecond;
+ PRECT prcFirst, prcSecond;
+ /* Lock them in good order */
+ if(pdc2)
{
- if (CreateAsIC)
+ if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock)
{
- if (! IntPrepareDriverIfNeeded())
- {
- /* Here, we have two possibilities:
- * a) return NULL, and hope that the caller
- * won't call us in a loop
- * b) bugcheck, but caller is unable to
- * react on the problem
- */
- /*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n");
- return NULL;*/
- KeBugCheck(VIDEO_DRIVER_INIT_FAILURE);
- }
+ pdcFirst = pdc1;
+ prcFirst = &rc1;
+ pdcSecond = pdc2;
+ prcSecond = &rc2;
}
else
{
- calledFromUser = UserIsEntered();
- if (!calledFromUser)
- {
- UserEnterExclusive();
- }
-
- if (! co_IntGraphicsCheck(TRUE))
- {
- if (!calledFromUser)
- {
- UserLeave();
- }
- DPRINT1("Unable to initialize graphics, returning NULL dc\n");
- return NULL;
- }
-
- if (!calledFromUser)
- {
- UserLeave();
- }
-
+ pdcFirst = pdc2;
+ prcFirst = &rc2;
+ pdcSecond = pdc1;
+ prcSecond = &rc1;
}
}
-
- /* Check for existing DC object */
- if ((hdc = DC_FindOpenDC(Driver)) != NULL)
+ else
{
- hdc = NtGdiCreateCompatibleDC(hdc);
- if (!hdc)
- DPRINT1("NtGdiCreateCompatibleDC() failed\n");
- return hdc;
+ pdcFirst = pdc1 ;
+ prcFirst = &rc1;
+ pdcSecond = NULL ;
}
- /* Allocate a DC object */
- pdc = DC_AllocDC(Driver);
- if (pdc == NULL)
+ if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT)
{
- DPRINT1("DC_AllocDC() failed\n");
- return NULL;
+ EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock);
+ MouseSafetyOnDrawStart(pdcFirst->ppdev,
+ prcFirst->left,
+ prcFirst->top,
+ prcFirst->right,
+ prcFirst->bottom) ;
+ /* Update surface if needed */
+ if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface)
+ {
+ DC_vUpdateDC(pdcFirst);
+ }
}
- hdc = pdc->BaseObject.hHmgr;
- pdcattr = pdc->pdcattr;
-
- pdc->dctype = DC_TYPE_DIRECT;
-
- pdc->dhpdev = PrimarySurface.dhpdev;
- if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device.
- pdc->ppdev = (PVOID)&PrimarySurface;
-
- // ATM we only have one display.
- pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY;
-
- pdc->flGraphicsCaps = PrimarySurface.devinfo.flGraphicsCaps;
- pdc->flGraphicsCaps2 = PrimarySurface.devinfo.flGraphicsCaps2;
-
- pdc->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE);
-
- pdcattr->jROP2 = R2_COPYPEN;
+ if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT)
+ {
+ EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock);
+ MouseSafetyOnDrawStart(pdcSecond->ppdev,
+ prcSecond->left,
+ prcSecond->top,
+ prcSecond->right,
+ prcSecond->bottom) ;
+ /* Update surface if needed */
+ if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface)
+ {
+ DC_vUpdateDC(pdcSecond);
+ }
+ }
+}
- pdc->erclWindow.top = pdc->erclWindow.left = 0;
- pdc->erclWindow.right = pdc->ppdev->gdiinfo.ulHorzRes;
- pdc->erclWindow.bottom = pdc->ppdev->gdiinfo.ulVertRes;
- pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW.
+/* Finishes a blit for one or two DCs */
+VOID
+FASTCALL
+DC_vFinishBlit(PDC pdc1, PDC pdc2)
+{
+ if(pdc1->dctype == DCTYPE_DIRECT)
+ {
+ MouseSafetyOnDrawEnd(pdc1->ppdev);
+ EngReleaseSemaphore(pdc1->ppdev->hsemDevLock);
+ }
- pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
+ if(pdc2)
+ {
+ if(pdc2->dctype == DCTYPE_DIRECT)
+ {
+ MouseSafetyOnDrawEnd(pdc2->ppdev);
+ EngReleaseSemaphore(pdc2->ppdev->hsemDevLock);
+ }
+ }
+}
- hVisRgn = IntSysCreateRectRgn(0, 0, pdc->ppdev->gdiinfo.ulHorzRes,
- pdc->ppdev->gdiinfo.ulVertRes);
+HDC
+NTAPI
+GreOpenDCW(
+ PUNICODE_STRING pustrDevice,
+ DEVMODEW *pdmInit,
+ PUNICODE_STRING pustrLogAddr,
+ ULONG iType,
+ BOOL bDisplay,
+ HANDLE hspool,
+ VOID *pDriverInfo2,
+ VOID *pUMdhpdev)
+{
+ PPDEVOBJ ppdev;
+ PDC pdc;
+ HDC hdc;
- if (!CreateAsIC)
- {
- pdc->pSurfInfo = NULL;
-// pdc->dclevel.pSurface =
- DC_UnlockDc(pdc);
+ DPRINT("GreOpenDCW(%S, iType=%ld)\n",
+ pustrDevice ? pustrDevice->Buffer : NULL, iType);
- /* Initialize the DC state */
- IntGdiSetTextColor(hdc, RGB(0, 0, 0));
- IntGdiSetBkColor(hdc, RGB(255, 255, 255));
- }
- else
+ /* Get a PDEVOBJ for the device */
+ ppdev = EngpGetPDEV(pustrDevice);
+ if (!ppdev)
{
- /* From MSDN2:
- The CreateIC function creates an information context for the specified device.
- The information context provides a fast way to get information about the
- device without creating a device context (DC). However, GDI drawing functions
- cannot accept a handle to an information context.
- */
- pdc->dctype = DC_TYPE_INFO;
-// pdc->pSurfInfo =
-// DC_vSelectSurface(pdc, NULL);
- pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255);
- pdcattr->crForegroundClr = RGB(0, 0, 0);
- DC_UnlockDc(pdc);
+ DPRINT1("Didn't find a suitable PDEV\n");
+ return NULL;
}
- DC_InitDC(hdc);
- if (hVisRgn)
+ DPRINT("GreOpenDCW - ppdev = %p\n", ppdev);
+
+ pdc = DC_AllocDcWithHandle();
+ if (!pdc)
{
- GdiSelectVisRgn(hdc, hVisRgn);
- REGION_FreeRgnByHandle(hVisRgn);
+ DPRINT1("Could not Allocate a DC\n");
+ PDEVOBJ_vRelease(ppdev);
+ return NULL;
}
+ hdc = pdc->BaseObject.hHmgr;
+
+ /* Lock ppdev and initialize the new DC */
+ DC_vInitDc(pdc, iType, ppdev);
+ /* FIXME: HACK! */
+ DC_InitHack(pdc);
+
+ DC_AllocDcAttr(pdc);
+
+ DC_UnlockDc(pdc);
- IntGdiSetTextAlign(hdc, TA_TOP);
- IntGdiSetBkMode(hdc, OPAQUE);
+ DPRINT("returning hdc = %p\n", hdc);
return hdc;
}
-
-HDC APIENTRY
+HDC
+APIENTRY
NtGdiOpenDCW(
- PUNICODE_STRING Device,
- DEVMODEW *InitData,
+ PUNICODE_STRING pustrDevice,
+ DEVMODEW *pdmInit,
PUNICODE_STRING pustrLogAddr,
ULONG iType,
BOOL bDisplay,
VOID *pDriverInfo2,
VOID *pUMdhpdev)
{
- UNICODE_STRING SafeDevice;
- DEVMODEW SafeInitData;
- PVOID Dhpdev;
- HDC Ret;
- NTSTATUS Status = STATUS_SUCCESS;
-
- if (!Device) return UserGetDesktopDC(iType,FALSE,TRUE);
-
- if (InitData)
+ UNICODE_STRING ustrDevice;
+ WCHAR awcDevice[CCHDEVICENAME];
+ DEVMODEW dmInit;
+ PVOID dhpdev;
+ HDC hdc;
+
+ /* Only if a devicename is given, we need any data */
+ if (pustrDevice)
{
+ /* Initialize destination string */
+ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice));
+
_SEH2_TRY
{
+ /* Probe the UNICODE_STRING and the buffer */
+ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1);
+ ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1);
+
+ /* Copy the string */
+ RtlCopyUnicodeString(&ustrDevice, pustrDevice);
+
+ if (pdmInit)
+ {
+ /* FIXME: could be larger */
+ ProbeForRead(pdmInit, sizeof(DEVMODEW), 1);
+ RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW));
+ }
+
if (pUMdhpdev)
{
- ProbeForWrite(pUMdhpdev, sizeof(PVOID), 1);
+ ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1);
}
- ProbeForRead(InitData, sizeof(DEVMODEW), 1);
- RtlCopyMemory(&SafeInitData, InitData, sizeof(DEVMODEW));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH2_GetExceptionCode();
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return NULL);
}
- _SEH2_END;
+ _SEH2_END
+ }
+ else
+ {
+ pdmInit = NULL;
+ pUMdhpdev = NULL;
+ }
- if (!NT_SUCCESS(Status))
+ /* FIXME: HACK! */
+ if (pustrDevice)
+ {
+ UNICODE_STRING ustrDISPLAY = RTL_CONSTANT_STRING(L"DISPLAY");
+ if (RtlEqualUnicodeString(&ustrDevice, &ustrDISPLAY, TRUE))
{
- SetLastNtError(Status);
- return NULL;
+ pustrDevice = NULL;
}
- /* FIXME - InitData can have some more bytes! */
}
- if (Device)
+ /* Call the internal function */
+ hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL,
+ pdmInit ? &dmInit : NULL,
+ NULL, // fixme pwszLogAddress
+ iType,
+ bDisplay,
+ hspool,
+ NULL, //FIXME: pDriverInfo2
+ pUMdhpdev ? &dhpdev : NULL);
+
+ /* If we got a HDC and a UM dhpdev is requested,... */
+ if (hdc && pUMdhpdev)
{
- Status = IntSafeCopyUnicodeString(&SafeDevice, Device);
- if (!NT_SUCCESS(Status))
+ /* Copy dhpdev to caller (FIXME: use dhpdev?? */
+ _SEH2_TRY
{
- SetLastNtError(Status);
- return NULL;
+ /* Pointer was already probed */
+ *(HANDLE*)pUMdhpdev = dhpdev;
}
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Ignore error */
+ }
+ _SEH2_END
}
- Ret = IntGdiCreateDC(Device ? &SafeDevice : NULL,
- NULL,
- pUMdhpdev ? &Dhpdev : NULL,
- InitData ? &SafeInitData : NULL,
- (BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW
-
- // FIXME!!!!
- if (pUMdhpdev) pUMdhpdev = Dhpdev;
-
- return Ret;
+ return hdc;
}
-HDC FASTCALL
-IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
+
+HDC
+APIENTRY
+NtGdiCreateCompatibleDC(HDC hdc)
{
- HDC hDC;
- UNICODE_STRING DriverName;
- RtlInitUnicodeString(&DriverName, L"DISPLAY");
+ HDC hdcNew;
+ PPDEVOBJ ppdev;
+ PDC pdc, pdcNew;
- if (DcType != DC_TYPE_MEMORY)
- hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
- else
- hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
-//
-// There is room to grow here~
-//
-
-//
-// If NULL, first time through! Build the default (was window) dc!
-// Setup clean DC state for the system.
-//
- if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
- { // This is a cheesy way to do this.
- PDC dc = DC_LockDc(hDC);
- HSURF hsurf;
- defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
- if (!defaultDCstate)
+ DPRINT("NtGdiCreateCompatibleDC(0x%p)\n", hdc);
+
+ /* Did the caller provide a DC? */
+ if (hdc)
+ {
+ /* Yes, try to lock it */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
{
- DC_UnlockDc(dc);
+ DPRINT1("Could not lock source DC %p\n", hdc);
return NULL;
}
- RtlZeroMemory(defaultDCstate, sizeof(DC));
- defaultDCstate->pdcattr = &defaultDCstate->dcattr;
- hsurf = (HSURF)PrimarySurface.pSurface; // HAX²
- defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
- DC_vCopyState(dc, defaultDCstate, TRUE);
- DC_UnlockDc(dc);
+
+ /* Get the pdev from the DC */
+ ppdev = pdc->ppdev;
+ InterlockedIncrement(&ppdev->cPdevRefs);
+
+ /* Unlock the source DC */
+ DC_UnlockDc(pdc);
}
- return hDC;
+ else
+ {
+ /* No DC given, get default device */
+ ppdev = EngpGetPDEV(NULL);
+ }
+
+ if (!ppdev)
+ {
+ DPRINT1("Didn't find a suitable PDEV\n");
+ return NULL;
+ }
+
+ /* Allocate a new DC */
+ pdcNew = DC_AllocDcWithHandle();
+ if (!pdcNew)
+ {
+ DPRINT1("Could not allocate a new DC\n");
+ PDEVOBJ_vRelease(ppdev);
+ return NULL;
+ }
+ hdcNew = pdcNew->BaseObject.hHmgr;
+
+ /* Lock ppdev and initialize the new DC */
+ DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev);
+ /* FIXME: HACK! */
+ DC_InitHack(pdcNew);
+
+ /* Allocate a dc attribute */
+ DC_AllocDcAttr(pdcNew);
+
+ // HACK!
+ DC_vSelectSurface(pdcNew, psurfDefaultBitmap);
+
+ DC_UnlockDc(pdcNew);
+
+ DPRINT("Leave NtGdiCreateCompatibleDC hdcNew = %p\n", hdcNew);
+
+ return hdcNew;
}
BOOL
if (!Force)
{
+ /* Windows permits NtGdiDeleteObjectApp to delete a permanent DC
+ * For some reason, it's still a valid handle, pointing to some kernel data.
+ * Not sure if this is a bug, a feature, some cache stuff... Who knows?
+ * See NtGdiDeleteObjectApp test for details */
if (DCToDelete->fs & DC_FLAG_PERMANENT)
{
- DPRINT1("No! You Naughty Application!\n");
DC_UnlockDc(DCToDelete);
- return UserReleaseDC(NULL, hDC, FALSE);
+ if(UserReleaseDC(NULL, hDC, FALSE))
+ {
+ /* ReactOs feature : call UserReleaseDC
+ * I don't think windows does it.
+ * Still, complain, no one should ever call DeleteDC
+ * on a window DC */
+ DPRINT1("No, you naughty application!\n");
+ return TRUE;
+ }
+ else
+ {
+ /* This is not a window owned DC.
+ * Force its deletion */
+ return IntGdiDeleteDC(hDC, TRUE);
+ }
}
}
- /* First delete all saved DCs */
- while (DCToDelete->dclevel.lSaveDepth > 1)
- {
- PDC savedDC;
- HDC savedHDC;
+ DC_UnlockDc(DCToDelete);
- savedHDC = DCToDelete->hdcNext;
- savedDC = DC_LockDc(savedHDC);
- if (savedDC == NULL)
+ if (!IsObjectDead(hDC))
+ {
+ if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC))
{
- break;
+ DPRINT1("DC_FreeDC failed\n");
}
- DCToDelete->hdcNext = savedDC->hdcNext;
- DCToDelete->dclevel.lSaveDepth--;
- DC_UnlockDc(savedDC);
- IntGdiDeleteDC(savedHDC, Force);
- }
-
- /* Free GDI resources allocated to this DC */
- if (!(DCToDelete->dclevel.flPath & DCPATH_SAVESTATE))
- {
- /*
- NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN);
- NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH);
- NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT);
- DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet */
- }
- if (DCToDelete->rosdc.hClipRgn)
- {
- GreDeleteObject(DCToDelete->rosdc.hClipRgn);
- }
- if (DCToDelete->prgnVis)
- {
- GreDeleteObject(DCToDelete->prgnVis->BaseObject.hHmgr);
- }
- if (NULL != DCToDelete->rosdc.CombinedClip)
- {
- IntEngDeleteClipRegion(DCToDelete->rosdc.CombinedClip);
- }
- if (DCToDelete->rosdc.hGCClipRgn)
- {
- GreDeleteObject(DCToDelete->rosdc.hGCClipRgn);
- }
- if (DCToDelete->dclevel.prgnMeta)
- {
- GreDeleteObject(((PROSRGNDATA)DCToDelete->dclevel.prgnMeta)->BaseObject.hHmgr);
}
- if (DCToDelete->prgnAPI)
+ else
{
- GreDeleteObject(((PROSRGNDATA)DCToDelete->prgnAPI)->BaseObject.hHmgr);
+ DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC);
}
- PATH_Delete(DCToDelete->dclevel.hPath);
-
- DC_UnlockDc(DCToDelete);
- GreDeleteObject(hDC);
+
return TRUE;
}
-HDC FASTCALL
-DC_FindOpenDC(PUNICODE_STRING Driver)
+BOOL
+APIENTRY
+NtGdiDeleteObjectApp(HANDLE DCHandle)
{
- return NULL;
-}
+ /* Complete all pending operations */
+ NtGdiFlushUserBatch();
-/*!
- * Initialize some common fields in the Device Context structure.
-*/
-VOID FASTCALL
-DC_InitDC(HDC DCHandle)
-{
-// NtGdiRealizeDefaultPalette(DCHandle);
+ if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
-//// Removed for now.. See above brush and pen.
-// NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
-// NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
-////
- //NtGdiSelectFont(DCHandle, hFont);
+ if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC)
+ return GreDeleteObject((HGDIOBJ) DCHandle);
- /*
- {
- int res;
- res = CLIPPING_UpdateGCRegion(DCToInit);
- ASSERT ( res != ERROR );
- }
- */
+ if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
+
+ if (!GDIOBJ_OwnedByCurrentProcess(DCHandle))
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
- /* Set virtual resolution */
- NtGdiSetVirtualResolution(DCHandle, 0, 0, 0, 0);
+ return IntGdiDeleteDC(DCHandle, FALSE);
}
BOOL
pdc->dctype = DC_TYPE_INFO;
pdc->dclevel.pSurface = NULL;
- PDEV_sizl(pdc->ppdev, &sizl);
+ PDEVOBJ_sizl(pdc->ppdev, &sizl);
if ( sizl.cx == pdc->dclevel.sizl.cx &&
sizl.cy == pdc->dclevel.sizl.cy )
return FALSE;
}
-HDC APIENTRY
-NtGdiCreateCompatibleDC(HDC hDC)
-{
- PDC pdcNew, pdcOld;
- PDC_ATTR pdcattrNew, pdcattrOld;
- HDC hdcNew, DisplayDC = NULL;
- UNICODE_STRING DriverName;
- DWORD Layout = 0;
- HSURF hsurf;
-
- if (hDC == NULL)
- {
- RtlInitUnicodeString(&DriverName, L"DISPLAY");
- DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE);
- if (NULL == DisplayDC)
- {
- DPRINT1("Failed to create DisplayDC\n");
- return NULL;
- }
- hDC = DisplayDC;
- }
-
- /* Allocate a new DC based on the original DC's device */
- pdcOld = DC_LockDc(hDC);
- if (NULL == pdcOld)
- {
- if (NULL != DisplayDC)
- {
- NtGdiDeleteObjectApp(DisplayDC);
- }
- DPRINT1("Failed to lock hDC\n");
- return NULL;
- }
- pdcNew = DC_AllocDC(&pdcOld->rosdc.DriverName);
- if (!pdcNew)
- {
- DPRINT1("Failed to create pdcNew\n");
- DC_UnlockDc(pdcOld);
- if (DisplayDC)
- {
- NtGdiDeleteObjectApp(DisplayDC);
- }
- return NULL;
- }
- hdcNew = pdcNew->BaseObject.hHmgr;
-
- pdcattrOld = pdcOld->pdcattr;
- pdcattrNew = pdcNew->pdcattr;
-
- /* Copy information from original DC to new DC */
- pdcNew->dclevel.hdcSave = hdcNew;
-
- pdcNew->dhpdev = pdcOld->dhpdev;
-
- /* DriverName is copied in the AllocDC routine */
- pdcattrNew->ptlWindowOrg = pdcattrOld->ptlWindowOrg;
- pdcattrNew->szlWindowExt = pdcattrOld->szlWindowExt;
- pdcattrNew->ptlViewportOrg = pdcattrOld->ptlViewportOrg;
- pdcattrNew->szlViewportExt = pdcattrOld->szlViewportExt;
-
- pdcNew->dctype = DC_TYPE_MEMORY; // Always!
- hsurf = NtGdiGetStockObject(DEFAULT_BITMAP);
- pdcNew->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
- pdcNew->ppdev = pdcOld->ppdev;
- pdcNew->dclevel.hpal = pdcOld->dclevel.hpal;
-
- pdcattrNew->lTextAlign = pdcattrOld->lTextAlign;
- pdcattrNew->lBkMode = pdcattrOld->lBkMode;
- pdcattrNew->jBkMode = pdcattrOld->jBkMode;
- pdcattrNew->jROP2 = pdcattrOld->jROP2;
- pdcattrNew->dwLayout = pdcattrOld->dwLayout;
- if (pdcattrOld->dwLayout & LAYOUT_ORIENTATIONMASK) Layout = pdcattrOld->dwLayout;
- pdcNew->dclevel.flPath = pdcOld->dclevel.flPath;
- pdcattrNew->ulDirty_ = pdcattrOld->ulDirty_;
- pdcattrNew->iCS_CP = pdcattrOld->iCS_CP;
-
- pdcNew->erclWindow.left = pdcNew->erclWindow.top = 0;
- pdcNew->erclWindow.right = pdcNew->erclWindow.bottom = 1;
- DC_UnlockDc(pdcNew);
- DC_UnlockDc(pdcOld);
- if (NULL != DisplayDC)
- {
- NtGdiDeleteObjectApp(DisplayDC);
- }
-
- if (Layout) NtGdiSetLayout(hdcNew, -1, Layout);
+HDC FASTCALL
+IntGdiCreateDC(
+ PUNICODE_STRING Driver,
+ PUNICODE_STRING pustrDevice,
+ PVOID pUMdhpdev,
+ CONST PDEVMODEW pdmInit,
+ BOOL CreateAsIC)
+{
+ HDC hdc;
+
+ hdc = GreOpenDCW(pustrDevice,
+ pdmInit,
+ NULL,
+ CreateAsIC ? DCTYPE_INFO :
+ (Driver ? DC_TYPE_DIRECT : DC_TYPE_DIRECT),
+ TRUE,
+ NULL,
+ NULL,
+ pUMdhpdev);
- DC_InitDC(hdcNew);
- return hdcNew;
+ return hdc;
}
-
-BOOL
-APIENTRY
-NtGdiDeleteObjectApp(HANDLE DCHandle)
+HDC FASTCALL
+IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
{
- GDIOBJTYPE ObjType;
-
- /* Complete all pending operations */
- NtGdiFlushUserBatch();
-
- if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE;
-
- if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE;
-
- ObjType = GDI_OBJECT_GET_TYPE_INDEX((ULONG_PTR)DCHandle);
-
- if (GreGetObjectOwner( DCHandle, ObjType))
- {
- switch(ObjType)
- {
- case GDIObjType_DC_TYPE:
- return IntGdiDeleteDC(DCHandle, FALSE);
+ HDC hDC;
+ UNIMPLEMENTED;
+ ASSERT(FALSE);
- case GDIObjType_RGN_TYPE:
- case GDIObjType_SURF_TYPE:
- case GDIObjType_PAL_TYPE:
- case GDIObjType_LFONT_TYPE:
- case GDIObjType_BRUSH_TYPE:
- return GreDeleteObject((HGDIOBJ) DCHandle);
+ if (DcType == DC_TYPE_MEMORY)
+ hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth!
+ else
+ hDC = IntGdiCreateDC(NULL, NULL, NULL, NULL, (DcType == DC_TYPE_INFO));
- default:
- return FALSE;
- }
- }
- return (DCHandle != NULL);
+ return hDC;
}
{
PDC_ATTR pdcattr = pdc->pdcattr;
+ /* Timo : The text brush should never be changed.
+ * Jérôme : Yeah, but its palette must be updated anyway! */
if(pdcattr->ulDirty_ & DIRTY_TEXT)
- EBRUSHOBJ_vUpdate(&pdc->eboText, pdc->eboText.pbrush, pdc);
+ EBRUSHOBJ_vUpdate(&pdc->eboText, pbrDefaultBrush, pdc);
/* Update the eboText's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr);
PDC_ATTR pdcattr = pdc->pdcattr;
if(pdcattr->ulDirty_ & DIRTY_BACKGROUND)
- EBRUSHOBJ_vUpdate(&pdc->eboBackground, pdc->eboBackground.pbrush, pdc);
+ EBRUSHOBJ_vUpdate(&pdc->eboBackground, pbrDefaultBrush, pdc);
/* Update the eboBackground's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
/* Is this a valid palette for this depth? */
if ((BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) <= 8
- && ppal->Mode == PAL_INDEXED) ||
+ && (ppal->flFlags & PAL_INDEXED)) ||
(BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) > 8))
{
/* Get old palette, set new one */
}
/* Get the handle for the old bitmap */
- psurfOld = pDC->dclevel.pSurface;
- hOrgBmp = psurfOld ? psurfOld->BaseObject.hHmgr : NULL;
+ ASSERT(pDC->dclevel.pSurface);
+ hOrgBmp = pDC->dclevel.pSurface->BaseObject.hHmgr;
+
+ /* Lock it, to be sure while we mess with it*/
+ psurfOld = SURFACE_LockSurface(hOrgBmp);
+
+ /* Reset hdc, this surface isn't selected anymore */
+ psurfOld->hdc = NULL;
/* Release the old bitmap, reference the new */
DC_vSelectSurface(pDC, psurfBmp);
+ /* And unlock it, now we're done */
+ SURFACE_UnlockSurface(psurfOld);
+
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
- psurfBmp->hDC = hDC;
+ psurfBmp->hdc = hDC;
+
/* FIXME; improve by using a region without a handle and selecting it */
hVisRgn = IntSysCreateRectRgn( 0,
if (pPath->state != PATH_Closed)
{
SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
+ DC_UnlockDc(pdc);
return FALSE;
}
FASTCALL
DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
{
+ DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr);
+
/* Copy full DC attribute */
*pdcDst->pdcattr = *pdcSrc->pdcattr;
-
+
+ /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */
+ /* The VisRectRegion field needs to be set to a valid state */
+
/* Mark some fields as dirty */
pdcDst->pdcattr->ulDirty_ |= 0x0012001f; // Note: Use if, To is FALSE....
pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal;
/* Handle references here correctly */
- DC_vSelectSurface(pdcDst, pdcSrc->dclevel.pSurface);
DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill);
DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine);
DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal);
}
-BOOL
-APIENTRY
-NtGdiRestoreDC(
- HDC hdc,
+VOID
+NTAPI
+DC_vRestoreDC(
+ IN PDC pdc,
INT iSaveLevel)
{
- PDC pdc, pdcSave;
+ PEPROCESS pepCurrentProcess;
HDC hdcSave;
+ PDC pdcSave;
- DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel);
+ ASSERT(iSaveLevel > 0);
+ DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
- /* Lock the original DC */
- pdc = DC_LockDc(hdc);
- if (!pdc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- ASSERT(pdc->dclevel.lSaveDepth > 0);
-
- /* Negative values are relative to the stack top */
- if (iSaveLevel < 0)
- iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel;
-
- /* Check if we have a valid instance */
- if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth)
- {
- DPRINT("Illegal save level, requested: %ld, current: %ld\n",
- iSaveLevel, pdc->dclevel.lSaveDepth);
- DC_UnlockDc(pdc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
+ /* Get current process */
+ pepCurrentProcess = PsGetCurrentProcess();
/* Loop the save levels */
while (pdc->dclevel.lSaveDepth > iSaveLevel)
{
hdcSave = pdc->dclevel.hdcSave;
+ DPRINT("RestoreDC = %p\n", hdcSave);
/* Set us as the owner */
- if (!IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_POWNED, FALSE ))
+ if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
{
/* Could not get ownership. That's bad! */
- DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n",
- hdcSave, hdc);
- return FALSE;
+ DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
+ hdcSave, pdc->BaseObject.hHmgr);
+ return;// FALSE;
}
/* Lock the saved dc */
{
/* WTF? Internal error! */
DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
- hdcSave, hdc);
- DC_UnlockDc(pdc);
- return FALSE;
+ hdcSave, pdc->BaseObject.hHmgr);
+ return;// FALSE;
}
/* Remove the saved dc from the queue */
/* Copy the state back */
DC_vCopyState(pdcSave, pdc, FALSE);
+ /* Only memory DC's change their surface */
+ if (pdc->dctype == DCTYPE_MEMORY)
+ DC_vSelectSurface(pdc, pdcSave->dclevel.pSurface);
+
// Restore Path by removing it, if the Save flag is set.
// BeginPath will takecare of the rest.
if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE)
pdc->dclevel.hPath = 0;
pdc->dclevel.flPath &= ~DCPATH_SAVE;
}
- // Attempt to plug the leak!
- if (pdcSave->rosdc.hClipRgn)
- {
- DPRINT("Have hClipRgn!\n");
- REGION_FreeRgnByHandle(pdcSave->rosdc.hClipRgn);
- }
- // FIXME! Handle prgnMeta!
}
+ /* Prevent save dc from being restored */
+ pdcSave->dclevel.lSaveDepth = 1;
+
+ /* Unlock it */
+ DC_UnlockDc(pdcSave);
/* Delete the saved dc */
GreDeleteObject(hdcSave);
}
+ DPRINT("Leave DC_vRestoreDC()\n");
+}
+
+
+
+BOOL
+APIENTRY
+NtGdiRestoreDC(
+ HDC hdc,
+ INT iSaveLevel)
+{
+ PDC pdc;
+
+ DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel);
+
+ /* Lock the original DC */
+ pdc = DC_LockDc(hdc);
+ if (!pdc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ ASSERT(pdc->dclevel.lSaveDepth > 0);
+
+ /* Negative values are relative to the stack top */
+ if (iSaveLevel < 0)
+ iSaveLevel = pdc->dclevel.lSaveDepth + iSaveLevel;
+
+ /* Check if we have a valid instance */
+ if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth)
+ {
+ DPRINT("Illegal save level, requested: %ld, current: %ld\n",
+ iSaveLevel, pdc->dclevel.lSaveDepth);
+ DC_UnlockDc(pdc);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Call the internal function */
+ DC_vRestoreDC(pdc, iSaveLevel);
+
DC_UnlockDc(pdc);
- DPRINT("Leaving NtGdiRestoreDC\n");
+ DPRINT("Leave NtGdiRestoreDC\n");
return TRUE;
}
PDC pdc, pdcSave;
INT lSaveDepth;
- DPRINT("NtGdiSaveDC(%lx)\n", hDC);
+ DPRINT("NtGdiSaveDC(%p)\n", hDC);
/* Lock the original dc */
pdc = DC_LockDc(hDC);
}
/* Allocate a new dc */
- pdcSave = DC_AllocDC(NULL);
+ pdcSave = DC_AllocDcWithHandle();
if (pdcSave == NULL)
{
DPRINT("Could not allocate a new DC\n");
}
hdcSave = pdcSave->BaseObject.hHmgr;
- /* Copy the current state */
- DC_vCopyState(pdc, pdcSave, TRUE);
+ InterlockedIncrement(&pdc->ppdev->cPdevRefs);
+ DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev);
+
+ /* Handle references here correctly */
+// pdcSrc->dclevel.pSurface = NULL;
+// pdcSrc->dclevel.pbrFill = NULL;
+// pdcSrc->dclevel.pbrLine = NULL;
+// pdcSrc->dclevel.ppal = NULL;
/* Make it a kernel handle
(FIXME: windows handles this different, see wiki)*/
- IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_NONE, FALSE);
+ GDIOBJ_SetOwnership(hdcSave, NULL);
+
+ /* Copy the current state */
+ DC_vCopyState(pdc, pdcSave, TRUE);
+
+ /* Only memory DC's change their surface */
+ if (pdc->dctype == DCTYPE_MEMORY)
+ DC_vSelectSurface(pdcSave, pdc->dclevel.pSurface);
/* Copy path. FIXME: why this way? */
pdcSave->dclevel.hPath = pdc->dclevel.hPath;
DC_UnlockDc(pdcSave);
DC_UnlockDc(pdc);
- DPRINT("Leave NtGdiSaveDC: %ld\n", lSaveDepth);
+ DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave);
return lSaveDepth;
}
if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
{
pSurface = pdc->dclevel.pSurface;
- if (pSurface && pSurface->flFlags & PDEV_SURFACE)
+ if (pSurface && pSurface->flags & PDEV_SURFACE)
{
rclClip.left += pdc->ppdev->ptlOrigion.x;
rclClip.top += pdc->ppdev->ptlOrigion.y;
#define NDEBUG
#include <debug.h>
-// TODO: proper implementation of LDEVOBJ and PDEVOBJ interface
-
-/*static*/ PDEVOBJ PrimarySurface;
-PPDEVOBJ pPrimarySurface = &PrimarySurface;
-static KEVENT VideoDriverNeedsPreparation;
-static KEVENT VideoDriverPrepared;
PDC defaultDCstate = NULL;
-PSIZEL
-FASTCALL
-PDEV_sizl(PPDEVOBJ ppdev, PSIZEL psizl)
-{
- if (ppdev->flFlags & PDEV_META_DEVICE)
- {
- psizl->cx = ppdev->ulHorzRes;
- psizl->cy = ppdev->ulVertRes;
- }
- else
- {
- psizl->cx = ppdev->gdiinfo.ulHorzRes;
- psizl->cy = ppdev->gdiinfo.ulVertRes;
- }
- return psizl;
-}
-
-NTSTATUS FASTCALL
-InitDcImpl(VOID)
-{
- KeInitializeEvent(&VideoDriverNeedsPreparation, SynchronizationEvent, TRUE);
- KeInitializeEvent(&VideoDriverPrepared, NotificationEvent, FALSE);
- return STATUS_SUCCESS;
-}
-
-
-static BOOLEAN FASTCALL
-GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- WCHAR DeviceNameBuffer[20];
- NTSTATUS Status;
-
- swprintf(DeviceNameBuffer, L"\\Device\\Video%lu", DisplayNumber);
- RtlInitUnicodeString(RegistryPath, NULL);
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].Name = DeviceNameBuffer;
- QueryTable[0].EntryContext = RegistryPath;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
- L"VIDEO",
- QueryTable,
- NULL,
- NULL);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("No \\Device\\Video%lu value in DEVICEMAP\\VIDEO found\n", DisplayNumber);
- return FALSE;
- }
-
- DPRINT("RegistryPath %wZ\n", RegistryPath);
-
- return TRUE;
-}
-
-
-NTSTATUS
-NTAPI
-EnumDisplayQueryRoutine(IN PWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength,
- IN PVOID Context,
- IN PVOID EntryContext)
-{
- if ((Context == NULL) && ((ValueType == REG_SZ) || (ValueType == REG_MULTI_SZ)))
- {
- *(PULONG)EntryContext = ValueLength;
- }
- else
- {
- DPRINT1("Value data: %S %d\n", ValueData, ValueLength);
- RtlCopyMemory(Context, ValueData, ValueLength);
- }
-
- return STATUS_SUCCESS;
-}
-
-static BOOL FASTCALL
-FindDriverFileNames(PUNICODE_STRING DriverFileNames, ULONG DisplayNumber)
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- UNICODE_STRING RegistryPath;
- NTSTATUS Status;
- PWCHAR DriverNames = NULL;
- ULONG Length = 0;
-
- if (! GetRegistryPath(&RegistryPath, DisplayNumber))
- {
- DPRINT("GetRegistryPath failed\n");
- return FALSE;
- }
-
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND;
- QueryTable[0].Name = L"InstalledDisplayDrivers";
- QueryTable[0].EntryContext = &Length;
- QueryTable[0].QueryRoutine = EnumDisplayQueryRoutine;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- RegistryPath.Buffer,
- QueryTable,
- NULL,
- NULL);
- // DPRINT1("Status: %lx\n", Status);
- if (Length)
- {
- DriverNames = ExAllocatePoolWithTag(PagedPool, Length, TAG_DRIVER);
- // DPRINT1("Length allocated: %d\n", Length);
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- RegistryPath.Buffer,
- QueryTable,
- DriverNames,
- NULL);
- if (!NT_SUCCESS(Status)) DriverNames = NULL;
- }
-
- ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY);
- if (! NT_SUCCESS(Status))
- {
- DPRINT1("No InstalledDisplayDrivers value in service entry found\n");
- return FALSE;
- }
-
- RtlInitUnicodeString(DriverFileNames, DriverNames);
- DriverFileNames->Length = Length;
- DriverFileNames->MaximumLength = Length;
- //DPRINT1("DriverFileNames %wZ\n", DriverFileNames);
-
- return TRUE;
-}
-
-
-static NTSTATUS APIENTRY
-DevModeCallback(IN PWSTR ValueName,
- IN ULONG ValueType,
- IN PVOID ValueData,
- IN ULONG ValueLength,
- IN PVOID Context,
- IN PVOID EntryContext)
-{
- PDEVMODEW DevMode = (PDEVMODEW) Context;
-
- DPRINT("Found registry value for name %S: type %d, length %d\n",
- ValueName, ValueType, ValueLength);
-
- if (REG_DWORD == ValueType && sizeof(DWORD) == ValueLength)
- {
- if (0 == _wcsicmp(ValueName, L"DefaultSettings.BitsPerPel"))
- {
- DevMode->dmBitsPerPel = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.Flags"))
- {
- DevMode->dmDisplayFlags = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.VRefresh"))
- {
- DevMode->dmDisplayFrequency = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XPanning"))
- {
- DevMode->dmPanningWidth = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XResolution"))
- {
- DevMode->dmPelsWidth = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YPanning"))
- {
- DevMode->dmPanningHeight = *((DWORD *) ValueData);
- }
- else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YResolution"))
- {
- DevMode->dmPelsHeight = *((DWORD *) ValueData);
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-
-static BOOL FASTCALL
-SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber)
-{
- UNICODE_STRING RegistryPath;
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- NTSTATUS Status;
- BOOLEAN Valid = TRUE;
-
- if (!GetRegistryPath(&RegistryPath, DisplayNumber))
- {
- DPRINT("GetRegistryPath failed\n");
- return FALSE;
- }
-
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].QueryRoutine = DevModeCallback;
- QueryTable[0].Flags = 0;
- QueryTable[0].Name = NULL;
- QueryTable[0].EntryContext = NULL;
- QueryTable[0].DefaultType = REG_NONE;
- QueryTable[0].DefaultData = NULL;
- QueryTable[0].DefaultLength = 0;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
- RegistryPath.Buffer,
- QueryTable,
- DevMode,
- NULL);
- if (! NT_SUCCESS(Status))
- {
- DPRINT("RtlQueryRegistryValues for %wZ failed with status 0x%08x\n",
- &RegistryPath, Status);
- Valid = FALSE;
- }
- else
- {
- DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n",
- DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency,
- DevMode->dmPelsWidth, DevMode->dmPelsHeight);
- if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency
- || 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight)
- {
- DPRINT("Not all required devmode members are set\n");
- Valid = FALSE;
- }
- }
-
- ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY);
-
- if (! Valid)
- {
- RtlZeroMemory(DevMode, sizeof(DEVMODEW));
- }
-
- return Valid;
-}
-
-static BOOL FASTCALL
-IntPrepareDriver(VOID)
-{
- PFN_DrvEnableDriver GDEnableDriver;
- DRVENABLEDATA DED;
- UNICODE_STRING DriverFileNames;
- PWSTR CurrentName;
- BOOL GotDriver;
- BOOL DoDefault;
- ULONG DisplayNumber;
- LARGE_INTEGER Zero;
- BOOLEAN ret = FALSE;
-
- Zero.QuadPart = 0;
- if (STATUS_SUCCESS != KeWaitForSingleObject(&VideoDriverNeedsPreparation, Executive, KernelMode, TRUE, &Zero))
- {
- /* Concurrent access. Wait for VideoDriverPrepared event */
- if (STATUS_SUCCESS == KeWaitForSingleObject(&VideoDriverPrepared, Executive, KernelMode, TRUE, NULL))
- ret = PrimarySurface.PreparedDriver;
- goto cleanup;
- }
- // HAX! Fixme so I can support more than one! So how many?
- for (DisplayNumber = 0; ; DisplayNumber++)
- {
- DPRINT("Trying to load display driver no. %d\n", DisplayNumber);
-
- RtlZeroMemory(&PrimarySurface, sizeof(PrimarySurface));
-
-// if (!pPrimarySurface) pPrimarySurface = ExAllocatePoolWithTag(PagedPool, gdwDirectDrawContext + sizeof(PDEVOBJ), TAG_GDIPDEV);
-
- PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(DisplayNumber);
-
- /* Open the miniport driver */
- if (PrimarySurface.VideoFileObject == NULL)
- {
- DPRINT1("FindMPDriver failed\n");
- goto cleanup;
- }
-
- /* Retrieve DDI driver names from registry */
- RtlInitUnicodeString(&DriverFileNames, NULL);
- if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
- {
- DPRINT1("FindDriverFileNames failed\n");
- continue;
- }
-
- /*
- * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
- * scan all of them until a good one found.
- */
- CurrentName = DriverFileNames.Buffer;
- GotDriver = FALSE;
- while (!GotDriver &&
- CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
- {
- /* Get the DDI driver's entry point */
- GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
- if (NULL == GDEnableDriver)
- {
- DPRINT("FindDDIDriver failed for %S\n", CurrentName);
- }
- else
- {
- /* Call DDI driver's EnableDriver function */
- RtlZeroMemory(&DED, sizeof(DED));
-
- if (! GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof(DED), &DED))
- {
- DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
- }
- else
- {
- GotDriver = TRUE;
- }
- }
-
- if (! GotDriver)
- {
- /* Skip to the next name but never get past the Unicode string */
- while (L'\0' != *CurrentName &&
- CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
- {
- CurrentName++;
- }
- if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)))
- {
- CurrentName++;
- }
- }
- }
-
- if (!GotDriver)
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
- DPRINT1("No suitable DDI driver found\n");
- continue;
- }
-
- DPRINT1("Display driver %S loaded\n", CurrentName);
-
- ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
-
- DPRINT("Building DDI Functions\n");
-
- /* Construct DDI driver function dispatch table */
- if (!DRIVER_BuildDDIFunctions(&DED, &PrimarySurface.DriverFunctions))
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("BuildDDIFunctions failed\n");
- goto cleanup;
- }
-
- /* Allocate a phyical device handle from the driver */
- // Support DMW.dmSize + DMW.dmDriverExtra & Alloc DMW then set prt pdmwDev.
- PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
- if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber))
- {
- PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV(
- &PrimarySurface.DMW,
- L"",
- HS_DDI_MAX,
- PrimarySurface.ahsurf,
- sizeof(PrimarySurface.gdiinfo),
- &PrimarySurface.gdiinfo,
- sizeof(PrimarySurface.devinfo),
- &PrimarySurface.devinfo,
- NULL,
- L"",
- (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
- DoDefault = (NULL == PrimarySurface.dhpdev);
- if (DoDefault)
- {
- DPRINT1("DrvEnablePDev with registry parameters failed\n");
- }
- }
- else
- {
- DoDefault = TRUE;
- }
-
- if (DoDefault)
- {
- RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW));
- PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW);
- PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV(
- &PrimarySurface.DMW,
- L"",
- HS_DDI_MAX,
- PrimarySurface.ahsurf,
- sizeof(PrimarySurface.gdiinfo),
- &PrimarySurface.gdiinfo,
- sizeof(PrimarySurface.devinfo),
- &PrimarySurface.devinfo,
- NULL,
- L"",
- (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject));
-
- if (NULL == PrimarySurface.dhpdev)
- {
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("DrvEnablePDEV with default parameters failed\n");
- DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n");
- continue;
- }
-
- // Update the primary surface with what we really got
- PrimarySurface.DMW.dmPelsWidth = PrimarySurface.gdiinfo.ulHorzRes;
- PrimarySurface.DMW.dmPelsHeight = PrimarySurface.gdiinfo.ulVertRes;
- PrimarySurface.DMW.dmBitsPerPel = PrimarySurface.gdiinfo.cBitsPixel;
- PrimarySurface.DMW.dmDisplayFrequency = PrimarySurface.gdiinfo.ulVRefresh;
- }
-
- if (!PrimarySurface.DMW.dmDriverExtra)
- {
- PrimarySurface.pdmwDev = &PrimarySurface.DMW; // HAX!
- }
- else
- {
- DPRINT1("WARNING!!! Need to Alloc DMW !!!!!!\n");
- }
- // Dont remove until we finish testing other drivers.
- if (PrimarySurface.DMW.dmDriverExtra != 0)
- {
- DPRINT1("**** DMW extra = %u bytes. Please report to ros-dev@reactos.org ****\n", PrimarySurface.DMW.dmDriverExtra);
- }
-
- if (0 == PrimarySurface.gdiinfo.ulLogPixelsX)
- {
- DPRINT("Adjusting gdiinfo.ulLogPixelsX\n");
- PrimarySurface.gdiinfo.ulLogPixelsX = 96;
- }
- if (0 == PrimarySurface.gdiinfo.ulLogPixelsY)
- {
- DPRINT("Adjusting gdiinfo.ulLogPixelsY\n");
- PrimarySurface.gdiinfo.ulLogPixelsY = 96;
- }
-
- PrimarySurface.Pointer.Exclude.right = -1;
-
- DPRINT("calling completePDev\n");
-
- /* Complete initialization of the physical device */
- PrimarySurface.DriverFunctions.CompletePDEV(
- PrimarySurface.dhpdev,
- (HDEV)&PrimarySurface);
-
- DPRINT("calling DRIVER_ReferenceDriver\n");
-
- DRIVER_ReferenceDriver(L"DISPLAY");
-
- PrimarySurface.PreparedDriver = TRUE;
- PrimarySurface.DisplayNumber = DisplayNumber;
- PrimarySurface.flFlags = PDEV_DISPLAY; // Hard set,, add more flags.
- PrimarySurface.hsemDevLock = (PERESOURCE)EngCreateSemaphore();
- // Should be null,, but make sure for now.
- PrimarySurface.pvGammaRamp = NULL;
- PrimarySurface.ppdevNext = NULL; // Fixme! We need to support more than display drvs.
- PrimarySurface.ppdevParent = NULL; // Always NULL if primary.
- PrimarySurface.pGraphicsDevice = NULL; // Fixme!
- PrimarySurface.pEDDgpl = ExAllocatePoolWithTag(PagedPool, sizeof(EDD_DIRECTDRAW_GLOBAL), TAG_EDDGBL);
- if (PrimarySurface.pEDDgpl)
- {
- RtlZeroMemory( PrimarySurface.pEDDgpl ,sizeof(EDD_DIRECTDRAW_GLOBAL));
- ret = TRUE;
- }
- goto cleanup;
- }
-
-cleanup:
- KeSetEvent(&VideoDriverPrepared, 1, FALSE);
- return ret;
-}
-
-BOOL FASTCALL
-IntPrepareDriverIfNeeded(VOID)
+VOID FASTCALL
+IntGdiReferencePdev(PPDEVOBJ ppdev)
{
- return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
+ UNIMPLEMENTED;
}
-static BOOL FASTCALL
-PrepareVideoPrt(VOID)
+VOID FASTCALL
+IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType)
{
- PIRP Irp;
- NTSTATUS Status;
- IO_STATUS_BLOCK Iosb;
- BOOL Prepare = TRUE;
- ULONG Length = sizeof(BOOL);
- PIO_STACK_LOCATION StackPtr;
- LARGE_INTEGER StartOffset;
- PFILE_OBJECT FileObject = PrimarySurface.VideoFileObject;
- PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
-
- DPRINT("PrepareVideoPrt() called\n");
-
- KeClearEvent(&PrimarySurface.VideoFileObject->Event);
-
- ObReferenceObjectByPointer(FileObject, 0, IoFileObjectType, KernelMode);
-
- StartOffset.QuadPart = 0;
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
- DeviceObject,
- (PVOID) &Prepare,
- Length,
- &StartOffset,
- NULL,
- &Iosb);
- if (NULL == Irp)
- {
- return FALSE;
- }
-
- /* Set up IRP Data */
- Irp->Tail.Overlay.OriginalFileObject = FileObject;
- Irp->RequestorMode = KernelMode;
- Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
- Irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
- Irp->Flags |= IRP_WRITE_OPERATION;
-
- /* Setup Stack Data */
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = PrimarySurface.VideoFileObject;
- StackPtr->Parameters.Write.Key = 0;
-
- Status = IoCallDriver(DeviceObject, Irp);
-
- if (STATUS_PENDING == Status)
- {
- KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, TRUE, 0);
- Status = Iosb.Status;
- }
-
- return NT_SUCCESS(Status);
+ UNIMPLEMENTED;
}
-
BOOL FASTCALL
-IntCreatePrimarySurface(VOID)
+IntCreatePrimarySurface()
{
SIZEL SurfSize;
- RECTL SurfaceRect;
- SURFOBJ *SurfObj;
+ SURFOBJ *pso;
BOOL calledFromUser;
- if (! IntPrepareDriverIfNeeded())
- {
- return FALSE;
- }
-
- if (! PrepareVideoPrt())
- {
- return FALSE;
- }
-
- DPRINT("calling EnableSurface\n");
- /* Enable the drawing surface */
- PrimarySurface.pSurface =
- PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.dhpdev);
- if (NULL == PrimarySurface.pSurface)
- {
- /* PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE);*/
- PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev);
- ObDereferenceObject(PrimarySurface.VideoFileObject);
- DPRINT1("DrvEnableSurface failed\n");
- return FALSE;
- }
-
- PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, TRUE);
-
calledFromUser = UserIsEntered(); //fixme: possibly upgrade a shared lock
if (!calledFromUser)
{
}
/* attach monitor */
- IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber);
+ IntAttachMonitor(gppdevPrimary, 0);
- SurfObj = EngLockSurface(PrimarySurface.pSurface);
- SurfObj->dhpdev = PrimarySurface.dhpdev;
- SurfSize = SurfObj->sizlBitmap;
- SurfaceRect.left = SurfaceRect.top = 0;
- SurfaceRect.right = SurfObj->sizlBitmap.cx;
- SurfaceRect.bottom = SurfObj->sizlBitmap.cy;
- /* FIXME - why does EngEraseSurface() sometimes crash?
- EngEraseSurface(SurfObj, &SurfaceRect, 0); */
+ DPRINT1("IntCreatePrimarySurface, pPrimarySurface=%p, pPrimarySurface->pSurface = %p\n",
+ pPrimarySurface, pPrimarySurface->pSurface);
- /* Put the pointer in the center of the screen */
- gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2;
- gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
+ /* Create surface */
+ pso = &PDEVOBJ_pSurface(pPrimarySurface)->SurfObj;
+ SurfSize = pso->sizlBitmap;
- /* Give the PDEV a MovePointer function */
- PrimarySurface.pfnMovePointer = PrimarySurface.DriverFunctions.MovePointer;
- if (!PrimarySurface.pfnMovePointer)
- PrimarySurface.pfnMovePointer = EngMovePointer;
+ /* Put the pointer in the center of the screen */
+ gpsi->ptCursor.x = pso->sizlBitmap.cx / 2;
+ gpsi->ptCursor.y = pso->sizlBitmap.cy / 2;
- EngUnlockSurface(SurfObj);
co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
// Init Primary Displays Device Capabilities.
- IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
+ PDEVOBJ_vGetDeviceCaps(pPrimarySurface, &GdiHandleTable->DevCaps);
if (!calledFromUser)
{
}
VOID FASTCALL
-IntDestroyPrimarySurface(VOID)
+IntDestroyPrimarySurface()
{
- BOOL calledFromUser;
-
- DRIVER_UnreferenceDriver(L"DISPLAY");
-
- calledFromUser = UserIsEntered();
- if (!calledFromUser)
- {
- UserEnterExclusive();
- }
-
- /* detach monitor */
- IntDetachMonitor(&PrimarySurface);
-
- if (!calledFromUser)
- {
- UserLeave();
- }
-
- /*
- * FIXME: Hide a mouse pointer there. Also because we have to prevent
- * memory leaks with the Eng* mouse routines.
- */
-
- DPRINT("Reseting display\n" );
- PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE);
- PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.dhpdev);
- PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev);
- PrimarySurface.PreparedDriver = FALSE;
- KeSetEvent(&VideoDriverNeedsPreparation, 1, FALSE);
- KeResetEvent(&VideoDriverPrepared);
-
- DceEmptyCache();
-
- ObDereferenceObject(PrimarySurface.VideoFileObject);
-}
-
-INT
-FASTCALL
-IntcFonts(PPDEVOBJ pDevObj)
-{
- ULONG_PTR Junk;
-// Msdn DrvQueryFont:
-// If the number of fonts in DEVINFO is -1 and iFace is zero, the driver
-// should return the number of fonts it supports.
- if ( pDevObj->devinfo.cFonts == -1)
- {
- if (pDevObj->DriverFunctions.QueryFont)
- pDevObj->devinfo.cFonts =
- (ULONG)pDevObj->DriverFunctions.QueryFont(pDevObj->dhpdev, 0, 0, &Junk);
- else
- pDevObj->devinfo.cFonts = 0;
- }
- return pDevObj->devinfo.cFonts;
-}
-
-//
-// Support multi display/device locks.
-//
-VOID
-FASTCALL
-DC_LockDisplay(HDC hDC)
-{
- PERESOURCE Resource;
- PDC dc = DC_LockDc(hDC);
- if (!dc) return;
- Resource = dc->ppdev->hsemDevLock;
- DC_UnlockDc(dc);
- if (!Resource) return;
- KeEnterCriticalRegion();
- ExAcquireResourceExclusiveLite( Resource , TRUE);
-}
-
-VOID
-FASTCALL
-DC_UnlockDisplay(HDC hDC)
-{
- PERESOURCE Resource;
- PDC dc = DC_LockDc(hDC);
- if (!dc) return;
- Resource = dc->ppdev->hsemDevLock;
- DC_UnlockDc(dc);
- if (!Resource) return;
- ExReleaseResourceLite( Resource );
- KeLeaveCriticalRegion();
+ UNIMPLEMENTED;
}
-//
-// Enumerate HDev
-//
PPDEVOBJ FASTCALL
IntEnumHDev(VOID)
{
// I guess we will soon have more than one primary surface.
// This will do for now.
- return &PrimarySurface;
+ return pPrimarySurface;
}
-VOID FASTCALL
-IntGdiReferencePdev(PPDEVOBJ ppdev)
-{
- if (!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore(); // Hax, should be in dllmain.c
- IntGdiAcquireSemaphore(hsemDriverMgmt);
- ppdev->cPdevRefs++;
- IntGdiReleaseSemaphore(hsemDriverMgmt);
-}
-
-VOID FASTCALL
-IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType)
-{
- IntGdiAcquireSemaphore(hsemDriverMgmt);
- ppdev->cPdevRefs--;
- if (!ppdev->cPdevRefs)
- {
- // Handle the destruction of ppdev or PDEVOBJ or PDEVOBJ or PDEV etc.
- }
- IntGdiReleaseSemaphore(hsemDriverMgmt);
-}
-
-
-
-INT
-FASTCALL
-IntGetColorManagementCaps(PPDEVOBJ pDevObj)
-{
- INT ret = CM_NONE;
-
- if ( pDevObj->flFlags & PDEV_DISPLAY)
- {
- if (pDevObj->devinfo.iDitherFormat == BMF_8BPP ||
- pDevObj->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP)
- ret = CM_GAMMA_RAMP;
- }
- if (pDevObj->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR)
- ret |= CM_CMYK_COLOR;
- if (pDevObj->devinfo.flGraphicsCaps & GCAPS_ICM)
- ret |= CM_DEVICE_ICM;
- return ret;
-}
-
-INT FASTCALL
-IntGdiGetDeviceCaps(PDC dc, INT Index)
-{
- INT ret = 0;
- PPDEVOBJ ppdev = dc->ppdev;
- /* Retrieve capability */
- switch (Index)
- {
- case DRIVERVERSION:
- ret = ppdev->gdiinfo.ulVersion;
- break;
-
- case TECHNOLOGY:
- ret = ppdev->gdiinfo.ulTechnology;
- break;
-
- case HORZSIZE:
- ret = ppdev->gdiinfo.ulHorzSize;
- break;
-
- case VERTSIZE:
- ret = ppdev->gdiinfo.ulVertSize;
- break;
-
- case HORZRES:
- ret = ppdev->gdiinfo.ulHorzRes;
- break;
-
- case VERTRES:
- ret = ppdev->gdiinfo.ulVertRes;
- break;
-
- case LOGPIXELSX:
- ret = ppdev->gdiinfo.ulLogPixelsX;
- break;
-
- case LOGPIXELSY:
- ret = ppdev->gdiinfo.ulLogPixelsY;
- break;
-
- case CAPS1:
- if ( ppdev->pGraphicsDevice &&
- (((PGRAPHICS_DEVICE)ppdev->pGraphicsDevice)->StateFlags &
- DISPLAY_DEVICE_MIRRORING_DRIVER))
- ret = C1_MIRRORING;
- break;
-
- case BITSPIXEL:
- ret = ppdev->gdiinfo.cBitsPixel;
- break;
-
- case PLANES:
- ret = ppdev->gdiinfo.cPlanes;
- break;
-
- case NUMBRUSHES:
- ret = -1;
- break;
-
- case NUMPENS:
- ret = ppdev->gdiinfo.ulNumColors;
- if ( ret != -1 ) ret *= 5;
- break;
-
- case NUMFONTS:
- ret = IntcFonts(ppdev);
- break;
-
- case NUMCOLORS:
- ret = ppdev->gdiinfo.ulNumColors;
- break;
-
- case ASPECTX:
- ret = ppdev->gdiinfo.ulAspectX;
- break;
-
- case ASPECTY:
- ret = ppdev->gdiinfo.ulAspectY;
- break;
-
- case ASPECTXY:
- ret = ppdev->gdiinfo.ulAspectXY;
- break;
-
- case CLIPCAPS:
- ret = CP_RECTANGLE;
- break;
-
- case SIZEPALETTE:
- ret = ppdev->gdiinfo.ulNumPalReg;
- break;
-
- case NUMRESERVED:
- ret = 20;
- break;
-
- case COLORRES:
- ret = ppdev->gdiinfo.ulDACRed +
- ppdev->gdiinfo.ulDACGreen +
- ppdev->gdiinfo.ulDACBlue;
- break;
-
- case DESKTOPVERTRES:
- ret = ppdev->gdiinfo.ulVertRes;
- break;
-
- case DESKTOPHORZRES:
- ret = ppdev->gdiinfo.ulHorzRes;
- break;
-
- case BLTALIGNMENT:
- ret = ppdev->gdiinfo.ulBltAlignment;
- break;
-
- case SHADEBLENDCAPS:
- ret = ppdev->gdiinfo.flShadeBlend;
- break;
-
- case COLORMGMTCAPS:
- ret = IntGetColorManagementCaps(ppdev);
- break;
-
- case PHYSICALWIDTH:
- ret = ppdev->gdiinfo.szlPhysSize.cx;
- break;
-
- case PHYSICALHEIGHT:
- ret = ppdev->gdiinfo.szlPhysSize.cy;
- break;
-
- case PHYSICALOFFSETX:
- ret = ppdev->gdiinfo.ptlPhysOffset.x;
- break;
-
- case PHYSICALOFFSETY:
- ret = ppdev->gdiinfo.ptlPhysOffset.y;
- break;
-
- case VREFRESH:
- ret = ppdev->gdiinfo.ulVRefresh;
- break;
-
- case RASTERCAPS:
- ret = ppdev->gdiinfo.flRaster;
- break;
-
- case CURVECAPS:
- ret = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
- CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
- break;
-
- case LINECAPS:
- ret = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
- LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
- break;
-
- case POLYGONALCAPS:
- ret = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
- PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
- break;
-
- case TEXTCAPS:
- ret = ppdev->gdiinfo.flTextCaps;
- if (ppdev->gdiinfo.ulTechnology) ret |= TC_VA_ABLE;
- ret |= (TC_SO_ABLE|TC_UA_ABLE);
- break;
-
- case PDEVICESIZE:
- case SCALINGFACTORX:
- case SCALINGFACTORY:
- default:
- ret = 0;
- break;
- }
-
- return ret;
-}
-
-INT APIENTRY
-NtGdiGetDeviceCaps(HDC hDC,
- INT Index)
-{
- PDC dc;
- INT ret;
-
- dc = DC_LockDc(hDC);
- if (dc == NULL)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- ret = IntGdiGetDeviceCaps(dc, Index);
-
- DPRINT("(%04x,%d): returning %d\n", hDC, Index, ret);
-
- DC_UnlockDc( dc );
- return ret;
-}
-
-VOID
-FASTCALL
-IntvGetDeviceCaps(
- PPDEVOBJ pDevObj,
- PDEVCAPS pDevCaps)
-{
- ULONG Tmp = 0;
- PGDIINFO pGdiInfo = &pDevObj->gdiinfo;
-
- pDevCaps->ulVersion = pGdiInfo->ulVersion;
- pDevCaps->ulTechnology = pGdiInfo->ulTechnology;
- pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000;
- pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000;
- pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize;
- pDevCaps->ulVertSize = pGdiInfo->ulVertSize;
- pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes;
- pDevCaps->ulVertRes = pGdiInfo->ulVertRes;
- pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh;
- pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes;
- pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes;
- pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment;
- pDevCaps->ulPlanes = pGdiInfo->cPlanes;
-
- pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel;
- if (pGdiInfo->cBitsPixel == 15) pDevCaps->ulBitsPixel = 16;
-
- Tmp = pGdiInfo->ulNumColors;
- if ( Tmp != -1 ) Tmp *= 5;
- pDevCaps->ulNumPens = Tmp;
- pDevCaps->ulNumColors = pGdiInfo->ulNumColors;
-
- pDevCaps->ulNumFonts = IntcFonts(pDevObj);
-
- pDevCaps->ulRasterCaps = pGdiInfo->flRaster;
- pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend;
- pDevCaps->ulAspectX = pGdiInfo->ulAspectX;
- pDevCaps->ulAspectY = pGdiInfo->ulAspectY;
- pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY;
- pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX;
- pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY;
- pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg;
- pDevCaps->ulColorRes = pGdiInfo->ulDACRed + pGdiInfo->ulDACGreen + pGdiInfo->ulDACBlue;
- pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx;
- pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy;
- pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x;
- pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y;
- pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes;
- pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes;
- pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment;
- pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment;
-
- Tmp = 0;
- Tmp = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
-
- pDevCaps->ulTextCaps = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER);
-
- if (pGdiInfo->ulTechnology)
- pDevCaps->ulTextCaps = Tmp | TC_VA_ABLE;
-
- pDevCaps->ulColorMgmtCaps = IntGetColorManagementCaps(pDevObj);
-
- return;
-}
-
-/*
-* @implemented
-*/
-BOOL
-APIENTRY
-NtGdiGetDeviceCapsAll (
- IN HDC hDC,
- OUT PDEVCAPS pDevCaps)
-{
- PDC dc;
- PDEVCAPS pSafeDevCaps;
- NTSTATUS Status = STATUS_SUCCESS;
-
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- pSafeDevCaps = ExAllocatePoolWithTag(PagedPool, sizeof(DEVCAPS), TAG_TEMP);
-
- if (!pSafeDevCaps)
- {
- DC_UnlockDc(dc);
- return FALSE;
- }
-
- IntvGetDeviceCaps(dc->ppdev, pSafeDevCaps);
-
- _SEH2_TRY
- {
- ProbeForWrite(pDevCaps,
- sizeof(DEVCAPS),
- 1);
- RtlCopyMemory(pDevCaps, pSafeDevCaps, sizeof(DEVCAPS));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
-
- ExFreePoolWithTag(pSafeDevCaps, TAG_TEMP);
- DC_UnlockDc(dc);
-
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return FALSE;
- }
- return TRUE;
-}
-
-
-/*
- * @implemented
- */
-DHPDEV
-APIENTRY
-NtGdiGetDhpdev(
- IN HDEV hdev)
-{
- PPDEVOBJ ppdev, pGdiDevice = (PPDEVOBJ) hdev;
- if (!pGdiDevice) return NULL;
- if ( pGdiDevice < (PPDEVOBJ)MmSystemRangeStart) return NULL;
- ppdev = pPrimarySurface;
- IntGdiAcquireSemaphore(hsemDriverMgmt);
- do
- {
- if (pGdiDevice == ppdev) break;
- else
- ppdev = ppdev->ppdevNext;
- }
- while (ppdev != NULL);
- IntGdiReleaseSemaphore(hsemDriverMgmt);
- if (!ppdev) return NULL;
- return pGdiDevice->dhpdev;
-}
-
-static NTSTATUS FASTCALL
-GetVideoRegistryKey(
- OUT PUNICODE_STRING RegistryPath,
- IN PCUNICODE_STRING DeviceName) /* ex: "\Device\Video0" */
-{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- NTSTATUS Status;
-
- RtlInitUnicodeString(RegistryPath, NULL);
- RtlZeroMemory(QueryTable, sizeof(QueryTable));
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].Name = DeviceName->Buffer;
- QueryTable[0].EntryContext = RegistryPath;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
- L"VIDEO",
- QueryTable,
- NULL,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("No %wZ value in DEVICEMAP\\VIDEO found (Status 0x%08lx)\n", DeviceName, Status);
- return STATUS_NO_SUCH_DEVICE;
- }
-
- DPRINT("RegistryPath %wZ\n", RegistryPath);
- return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS FASTCALL
-GetVideoDeviceName(
- OUT PUNICODE_STRING VideoDeviceName,
- IN PCUNICODE_STRING DisplayDevice) /* ex: "\.\DISPLAY1" or "\??\DISPLAY1" */
-{
- UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\??\\");
- UNICODE_STRING ObjectName;
- UNICODE_STRING KernelModeName = { 0, };
- OBJECT_ATTRIBUTES ObjectAttributes;
- USHORT LastSlash;
- ULONG Length;
- HANDLE LinkHandle = NULL;
- NTSTATUS Status;
-
- RtlInitUnicodeString(VideoDeviceName, NULL);
-
- /* Get device name (DisplayDevice is "\.\xxx") */
- for (LastSlash = DisplayDevice->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--)
- {
- if (DisplayDevice->Buffer[LastSlash - 1] == L'\\')
- break;
- }
-
- if (LastSlash == 0)
- {
- DPRINT1("Invalid device name '%wZ'\n", DisplayDevice);
- Status = STATUS_OBJECT_NAME_INVALID;
- goto cleanup;
- }
- ObjectName = *DisplayDevice;
- ObjectName.Length -= LastSlash * sizeof(WCHAR);
- ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR);
- ObjectName.Buffer += LastSlash;
-
- /* Create "\??\xxx" (ex: "\??\DISPLAY1") */
- KernelModeName.MaximumLength = Prefix.Length + ObjectName.Length + sizeof(UNICODE_NULL);
- KernelModeName.Buffer = ExAllocatePoolWithTag(PagedPool,
- KernelModeName.MaximumLength,
- TAG_DC);
- if (!KernelModeName.Buffer)
- {
- Status = STATUS_NO_MEMORY;
- goto cleanup;
- }
- RtlCopyUnicodeString(&KernelModeName, &Prefix);
- Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName);
- if (!NT_SUCCESS(Status))
- goto cleanup;
-
- /* Open \??\xxx (ex: "\??\DISPLAY1") */
- InitializeObjectAttributes(&ObjectAttributes,
- &KernelModeName,
- OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
- Status = ZwOpenSymbolicLinkObject(&LinkHandle,
- GENERIC_READ,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to open symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
- Status = STATUS_NO_SUCH_DEVICE;
- goto cleanup;
- }
-
- Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, &Length);
- if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
- Status = STATUS_NO_SUCH_DEVICE;
- goto cleanup;
- }
- VideoDeviceName->MaximumLength = Length;
- VideoDeviceName->Buffer = ExAllocatePoolWithTag(PagedPool,
- VideoDeviceName->MaximumLength + sizeof(UNICODE_NULL),
- TAG_DC);
- if (!VideoDeviceName->Buffer)
- {
- Status = STATUS_NO_MEMORY;
- goto cleanup;
- }
- Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, NULL);
- VideoDeviceName->Buffer[VideoDeviceName->MaximumLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status);
- Status = STATUS_NO_SUCH_DEVICE;
- goto cleanup;
- }
- Status = STATUS_SUCCESS;
-
-cleanup:
- if (!NT_SUCCESS(Status) && VideoDeviceName->Buffer)
- ExFreePoolWithTag(VideoDeviceName->Buffer, TAG_DC);
- if (KernelModeName.Buffer)
- ExFreePoolWithTag(KernelModeName.Buffer, TAG_DC);
- if (LinkHandle)
- ZwClose(LinkHandle);
- return Status;
-}
-
-LONG
-FASTCALL
-IntChangeDisplaySettings(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- IN LPDEVMODEW DevMode,
- IN DWORD dwflags,
- IN PVOID lParam OPTIONAL)
-{
- BOOLEAN NoReset = FALSE;
- BOOLEAN Reset = FALSE;
- LONG Ret = DISP_CHANGE_SUCCESSFUL;
- NTSTATUS Status ;
-
- DPRINT1("display flags : %x\n",dwflags);
-
- if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
- {
- /* Check global, reset and noreset flags */
- if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL)
- DPRINT1("CDS_GLOBAL unhandled");
- if ((dwflags & CDS_NORESET) == CDS_NORESET)
- NoReset = TRUE;
- dwflags &= ~(CDS_GLOBAL | CDS_NORESET);
- }
- if ((dwflags & CDS_RESET) == CDS_RESET)
- Reset = TRUE;
- if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY)
- DPRINT1("CDS_SET_PRIMARY unhandled");
- dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY);
-
- if (Reset && NoReset)
- return DISP_CHANGE_BADFLAGS;
-
- if (dwflags == 0)
- {
- /* Dynamically change graphics mode */
- DPRINT1("flag 0 UNIMPLEMENTED\n");
- SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
- return DISP_CHANGE_FAILED;
- }
-
- if ((dwflags & CDS_TEST) == CDS_TEST)
- {
- /* Test resolution */
- dwflags &= ~CDS_TEST;
- Status = IntEnumDisplaySettings(pDeviceName, ENUM_REGISTRY_SETTINGS, DevMode, 0);
- if (!NT_SUCCESS(Status))
- Ret = DISP_CHANGE_BADMODE;
- return Ret;
- }
-
- if ((dwflags & CDS_FULLSCREEN) == CDS_FULLSCREEN)
- {
- DEVMODEW lpDevMode;
- /* Full Screen */
- dwflags &= ~CDS_FULLSCREEN;
- DPRINT1("flag CDS_FULLSCREEN partially implemented\n");
- Ret = DISP_CHANGE_FAILED;
-
- RtlZeroMemory(&lpDevMode, sizeof(DEVMODEW));
- lpDevMode.dmSize = sizeof(DEVMODEW);
-
- Status = IntEnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &lpDevMode, 0);
- if (!NT_SUCCESS(Status))
- return DISP_CHANGE_FAILED;
-
- DPRINT1("Req Mode : %d x %d x %d\n", DevMode->dmPelsWidth,DevMode->dmPelsHeight,DevMode->dmBitsPerPel);
- DPRINT1("Current Mode : %d x %d x %d\n", lpDevMode.dmPelsWidth,lpDevMode.dmPelsHeight, lpDevMode.dmBitsPerPel);
-
-
- if ((lpDevMode.dmBitsPerPel == DevMode->dmBitsPerPel) &&
- (lpDevMode.dmPelsWidth == DevMode->dmPelsWidth) &&
- (lpDevMode.dmPelsHeight == DevMode->dmPelsHeight))
- Ret = DISP_CHANGE_SUCCESSFUL;
- }
-
- if ((dwflags & CDS_VIDEOPARAMETERS) == CDS_VIDEOPARAMETERS)
- {
- dwflags &= ~CDS_VIDEOPARAMETERS;
- if (lParam == NULL)
- Ret=DISP_CHANGE_BADPARAM;
- else
- {
- DPRINT1("flag CDS_VIDEOPARAMETERS UNIMPLEMENTED\n");
- Ret = DISP_CHANGE_FAILED;
- SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED);
- }
-
- }
-
- if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY)
- {
-
- UNICODE_STRING DeviceName;
- UNICODE_STRING RegistryKey;
- UNICODE_STRING InDeviceName;
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE DevInstRegKey;
- ULONG NewValue;
-
- DPRINT1("set CDS_UPDATEREGISTRY\n");
-
- dwflags &= ~CDS_UPDATEREGISTRY;
-
- /* Check if pDeviceName is NULL, we need to retrieve it */
- if (pDeviceName == NULL)
- {
- WCHAR szBuffer[MAX_DRIVER_NAME];
- PDC DC;
- PWND Wnd=NULL;
- HWND hWnd;
- HDC hDC;
-
- hWnd = IntGetDesktopWindow();
- if (!(Wnd = UserGetWindowObject(hWnd)))
- {
- return FALSE;
- }
-
- hDC = UserGetWindowDC(Wnd);
-
- DC = DC_LockDc(hDC);
- if (NULL == DC)
- {
- return FALSE;
- }
- swprintf (szBuffer, L"\\\\.\\DISPLAY%lu", DC->ppdev->DisplayNumber);
- DC_UnlockDc(DC);
-
- RtlInitUnicodeString(&InDeviceName, szBuffer);
- pDeviceName = &InDeviceName;
- }
-
- Status = GetVideoDeviceName(&DeviceName, pDeviceName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to get destination of '%wZ' (Status 0x%08lx)\n", pDeviceName, Status);
- return DISP_CHANGE_FAILED;
- }
- Status = GetVideoRegistryKey(&RegistryKey, &DeviceName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to get registry key for '%wZ' (Status 0x%08lx)\n", &DeviceName, Status);
- ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
- return DISP_CHANGE_FAILED;
- }
- ExFreePoolWithTag(DeviceName.Buffer, TAG_DC);
-
- InitializeObjectAttributes(&ObjectAttributes, &RegistryKey,
- OBJ_CASE_INSENSITIVE, NULL, NULL);
- Status = ZwOpenKey(&DevInstRegKey, KEY_SET_VALUE, &ObjectAttributes);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Unable to open registry key %wZ (Status 0x%08lx)\n", &RegistryKey, Status);
- ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY);
- return DISP_CHANGE_FAILED;
- }
- ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY);
-
- /* Update needed fields */
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel");
- NewValue = DevMode->dmBitsPerPel;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution");
- NewValue = DevMode->dmPelsWidth;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution");
- NewValue = DevMode->dmPelsHeight;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- if (NT_SUCCESS(Status) && DevMode->dmFields & DM_DISPLAYFREQUENCY)
- {
- RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.VRefresh");
- NewValue = DevMode->dmDisplayFrequency;
- Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue));
- }
-
- ZwClose(DevInstRegKey);
- if (NT_SUCCESS(Status))
- Ret = DISP_CHANGE_RESTART;
- else
- /* return DISP_CHANGE_NOTUPDATED when we can save to reg only valid for NT */
- Ret = DISP_CHANGE_NOTUPDATED;
- }
-
- if (dwflags != 0)
- Ret = DISP_CHANGE_BADFLAGS;
-
- DPRINT("IntChangeDisplaySettings returning %x\n", Ret);
- return Ret;
-}
-
-
-
-#define SIZEOF_DEVMODEW_300 188
-#define SIZEOF_DEVMODEW_400 212
-#define SIZEOF_DEVMODEW_500 220
-
-static NTSTATUS FASTCALL
-GetDisplayNumberFromDeviceName(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- OUT ULONG *DisplayNumber)
-{
- UNICODE_STRING DisplayString = RTL_CONSTANT_STRING(L"\\\\.\\DISPLAY");
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Length;
- ULONG Number;
- ULONG i;
-
- if (DisplayNumber == NULL)
- return STATUS_INVALID_PARAMETER_2;
-
- /* Check if DeviceName is valid */
- if (pDeviceName &&
- pDeviceName->Length > 0 && pDeviceName->Length <= DisplayString.Length)
- return STATUS_OBJECT_NAME_INVALID;
-
- if (pDeviceName == NULL || pDeviceName->Length == 0)
- {
- PWND DesktopObject;
- HDC DesktopHDC;
- PDC pDC;
-
- DesktopObject = UserGetDesktopWindow();
- DesktopHDC = UserGetWindowDC(DesktopObject);
- pDC = DC_LockDc(DesktopHDC);
-
- *DisplayNumber = pDC->ppdev->DisplayNumber;
-
- DC_UnlockDc(pDC);
- UserReleaseDC(DesktopObject, DesktopHDC, FALSE);
-
- return STATUS_SUCCESS;
- }
-
- /* Hack to check if the first parts are equal, by faking the device name length */
- Length = pDeviceName->Length;
- pDeviceName->Length = DisplayString.Length;
- if (RtlEqualUnicodeString(&DisplayString, pDeviceName, FALSE) == FALSE)
- Status = STATUS_OBJECT_NAME_INVALID;
- pDeviceName->Length = Length;
-
- if (NT_SUCCESS(Status))
- {
- /* Convert the last part of pDeviceName to a number */
- Number = 0;
- Length = pDeviceName->Length / sizeof(WCHAR);
- for (i = DisplayString.Length / sizeof(WCHAR); i < Length; i++)
- {
- WCHAR Char = pDeviceName->Buffer[i];
- if (Char >= L'0' && Char <= L'9')
- Number = Number * 10 + Char - L'0';
- else if (Char != L'\0')
- return STATUS_OBJECT_NAME_INVALID;
- }
-
- *DisplayNumber = Number - 1;
- }
-
- return Status;
-}
-
-/*! \brief Enumerate possible display settings for the given display...
- *
- * \todo Make thread safe!?
- * \todo Don't ignore pDeviceName
- * \todo Implement non-raw mode (only return settings valid for driver and monitor)
- */
-NTSTATUS
-FASTCALL
-IntEnumDisplaySettings(
- IN PUNICODE_STRING pDeviceName OPTIONAL,
- IN DWORD iModeNum,
- IN OUT LPDEVMODEW pDevMode,
- IN DWORD dwFlags)
-{
- static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
- static DWORD SizeOfCachedDevModes = 0;
- static UNICODE_STRING CachedDeviceName;
- PDEVMODEW CachedMode = NULL;
- DEVMODEW DevMode;
- ULONG DisplayNumber;
- NTSTATUS Status;
-
- Status = GetDisplayNumberFromDeviceName(pDeviceName, &DisplayNumber);
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
- if (pDevMode != NULL)
- {
- DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize);
- DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra);
- if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 &&
- pDevMode->dmSize != SIZEOF_DEVMODEW_400 &&
- pDevMode->dmSize != SIZEOF_DEVMODEW_500)
- {
- return STATUS_BUFFER_TOO_SMALL;
- }
- }
-
- if (iModeNum == ENUM_CURRENT_SETTINGS)
- {
- CachedMode = &PrimarySurface.DMW;
- ASSERT(CachedMode->dmSize > 0);
- }
- else if (iModeNum == ENUM_REGISTRY_SETTINGS)
- {
- RtlZeroMemory(&DevMode, sizeof (DevMode));
- DevMode.dmSize = sizeof (DevMode);
- DevMode.dmDriverExtra = 0;
- if (SetupDevMode(&DevMode, DisplayNumber))
- CachedMode = &DevMode;
- else
- {
- return STATUS_UNSUCCESSFUL; // FIXME: what status?
- }
- /* FIXME: Maybe look for the matching devmode supplied by the
- * driver so we can provide driver private/extra data?
- */
- }
- else
- {
- BOOL IsCachedDevice = (CachedDevModes != NULL);
-
- if (CachedDevModes &&
- ((pDeviceName == NULL && CachedDeviceName.Length > 0) ||
- (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length == 0) ||
- (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length > 0 && RtlEqualUnicodeString(pDeviceName, &CachedDeviceName, TRUE) == FALSE)))
- {
- IsCachedDevice = FALSE;
- }
-
- if (iModeNum == 0 || IsCachedDevice == FALSE) /* query modes from drivers */
- {
- UNICODE_STRING DriverFileNames;
- LPWSTR CurrentName;
- DRVENABLEDATA DrvEnableData;
-
- /* Free resources from last driver cache */
- if (IsCachedDevice == FALSE && CachedDeviceName.Buffer != NULL)
- {
- RtlFreeUnicodeString(&CachedDeviceName);
- }
-
- /* Retrieve DDI driver names from registry */
- RtlInitUnicodeString(&DriverFileNames, NULL);
- if (!FindDriverFileNames(&DriverFileNames, DisplayNumber))
- {
- DPRINT1("FindDriverFileNames failed\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- if (!IntPrepareDriverIfNeeded())
- {
- DPRINT1("IntPrepareDriverIfNeeded failed\n");
- return STATUS_UNSUCCESSFUL;
- }
-
- /*
- * DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
- * scan all of them until a good one found.
- */
- CurrentName = DriverFileNames.Buffer;
- for (;CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR));
- CurrentName += wcslen(CurrentName) + 1)
- {
- INT i;
- PFN_DrvEnableDriver GDEnableDriver;
- PFN_DrvGetModes GetModes = NULL;
- INT SizeNeeded, SizeUsed;
-
- /* Get the DDI driver's entry point */
- //GDEnableDriver = DRIVER_FindDDIDriver(CurrentName);
- GDEnableDriver = DRIVER_FindExistingDDIDriver(L"DISPLAY");
- if (NULL == GDEnableDriver)
- {
- DPRINT("FindDDIDriver failed for %S\n", CurrentName);
- continue;
- }
-
- /* Call DDI driver's EnableDriver function */
- RtlZeroMemory(&DrvEnableData, sizeof(DrvEnableData));
-
- if (!GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof (DrvEnableData), &DrvEnableData))
- {
- DPRINT("DrvEnableDriver failed for %S\n", CurrentName);
- continue;
- }
-
- CachedDevModesEnd = CachedDevModes;
-
- /* find DrvGetModes function */
- for (i = 0; i < DrvEnableData.c; i++)
- {
- PDRVFN DrvFn = DrvEnableData.pdrvfn + i;
-
- if (DrvFn->iFunc == INDEX_DrvGetModes)
- {
- GetModes = (PFN_DrvGetModes)DrvFn->pfn;
- break;
- }
- }
-
- if (GetModes == NULL)
- {
- DPRINT("DrvGetModes doesn't exist for %S\n", CurrentName);
- continue;
- }
-
- /* make sure we have enough memory to hold the modes */
- SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL);
- if (SizeNeeded <= 0)
- {
- DPRINT("DrvGetModes failed for %S\n", CurrentName);
- break;
- }
-
- SizeUsed = (PCHAR)CachedDevModesEnd - (PCHAR)CachedDevModes;
- if (SizeOfCachedDevModes < SizeUsed + SizeNeeded)
- {
- PVOID NewBuffer;
-
- SizeOfCachedDevModes += SizeNeeded;
- NewBuffer = ExAllocatePoolWithTag(PagedPool, SizeOfCachedDevModes, GDITAG_DEVMODE);
- if (NewBuffer == NULL)
- {
- /* clean up */
- ExFreePool(CachedDevModes);
- CachedDevModes = NULL;
- CachedDevModesEnd = NULL;
- SizeOfCachedDevModes = 0;
-
- if (CachedDeviceName.Buffer != NULL)
- RtlFreeUnicodeString(&CachedDeviceName);
-
- return STATUS_NO_MEMORY;
- }
- if (CachedDevModes != NULL)
- {
- RtlCopyMemory(NewBuffer, CachedDevModes, SizeUsed);
- ExFreePool(CachedDevModes);
- }
- CachedDevModes = NewBuffer;
- CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed);
- }
-
- if (!IsCachedDevice)
- {
- if (CachedDeviceName.Buffer != NULL)
- RtlFreeUnicodeString(&CachedDeviceName);
-
- if (pDeviceName)
- IntSafeCopyUnicodeString(&CachedDeviceName, pDeviceName);
-
- IsCachedDevice = TRUE;
- }
-
- /* query modes */
- SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject),
- SizeNeeded,
- CachedDevModesEnd);
- if (SizeNeeded <= 0)
- {
- DPRINT("DrvGetModes failed for %S\n", CurrentName);
- }
- else
- {
- CachedDevModesEnd = (DEVMODEW *)((PCHAR)CachedDevModesEnd + SizeNeeded);
- }
- }
-
- ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY);
- }
-
- /* return cached info */
- CachedMode = CachedDevModes;
- if (CachedMode >= CachedDevModesEnd)
- {
- return STATUS_NO_MORE_ENTRIES;
- }
- while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd)
- {
- ASSERT(CachedMode->dmSize > 0);
- CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra);
- }
- if (CachedMode >= CachedDevModesEnd)
- {
- return STATUS_NO_MORE_ENTRIES;
- }
- }
-
- ASSERT(CachedMode != NULL);
-
- if (pDevMode != NULL)
- {
- RtlCopyMemory(pDevMode, CachedMode, min(pDevMode->dmSize, CachedMode->dmSize));
- RtlZeroMemory(pDevMode + pDevMode->dmSize, pDevMode->dmDriverExtra);
- RtlCopyMemory(pDevMode + min(pDevMode->dmSize, CachedMode->dmSize), CachedMode + CachedMode->dmSize, min(pDevMode->dmDriverExtra, CachedMode->dmDriverExtra));
- }
-
- return STATUS_SUCCESS;
-}
-
INT
APIENTRY
NtGdiDrawEscape(
return 0;
}
+
{ 0xff, 0xff, 0xff, 0x00 }
};
+static const RGBTRIPLE EGAColorsTriples[16] = {
+/* rgbBlue, rgbGreen, rgbRed */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0x80, 0x80, 0x80 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0x00, 0x00, 0xff },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff }
+};
+
static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
{ 0x00, 0x00, 0x00, 0x00 },
{ 0xff, 0xff, 0xff, 0x00 }
};
+static const RGBQUAD DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
+/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
+ { 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x80 },
+ { 0x00, 0x80, 0x00 },
+ { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 },
+ { 0x80, 0x00, 0x80 },
+ { 0x80, 0x80, 0x00 },
+ { 0xc0, 0xc0, 0xc0 },
+ { 0xc0, 0xdc, 0xc0 },
+ { 0xf0, 0xca, 0xa6 },
+ { 0xf0, 0xfb, 0xff },
+ { 0xa4, 0xa0, 0xa0 },
+ { 0x80, 0x80, 0x80 },
+ { 0x00, 0x00, 0xf0 },
+ { 0x00, 0xff, 0x00 },
+ { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 },
+ { 0xff, 0x00, 0xff },
+ { 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff }
+};
+
UINT
APIENTRY
if (StartIndex + Entries > (1 << biBitCount))
Entries = (1 << biBitCount) - StartIndex;
- PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
- if (PalGDI == NULL)
+ if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
for (Index = StartIndex;
Index < StartIndex + Entries && Index < PalGDI->NumColors;
Index++)
if (StartIndex + Entries > (1 << biBitCount))
Entries = (1 << biBitCount) - StartIndex;
- PalGDI = PALETTE_LockPalette(psurf->hDIBPalette);
- if (PalGDI == NULL)
+ if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
+ PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr);
+
for (Index = StartIndex;
Index < StartIndex + Entries && Index < PalGDI->NumColors;
Index++)
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
- SURFACE *bitmap;
HBITMAP SourceBitmap;
+ PSURFACE psurfDst, psurfSrc;
INT result = 0;
- BOOL copyBitsResult;
- SURFOBJ *DestSurf, *SourceSurf;
- SIZEL SourceSize;
- POINTL ZeroPoint;
- RECTL DestRect;
- EXLATEOBJ exlo;
- PPALETTE ppalDDB, ppalDIB;
- //RGBQUAD *lpRGB;
- HPALETTE DDB_Palette, DIB_Palette;
- ULONG DIB_Palette_Type;
- INT DIBWidth;
-
- // Check parameters
- if (!(bitmap = SURFACE_LockSurface(hBitmap)))
- {
- return 0;
- }
-
- // Get RGB values
- //if (ColorUse == DIB_PAL_COLORS)
- // lpRGB = DIB_MapPaletteColors(hDC, bmi);
- //else
- // lpRGB = &bmi->bmiColors;
-
- DestSurf = &bitmap->SurfObj;
+ RECT rcDst;
+ POINTL ptSrc;
+ PVOID pvBits;
+ EXLATEOBJ exlo;
- // Create source surface
- SourceSize.cx = bmi->bmiHeader.biWidth;
- SourceSize.cy = ScanLines;
-
- // Determine width of DIB
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
-
- SourceBitmap = EngCreateBitmap(SourceSize,
- DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
- bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
- (PVOID) Bits);
- if (0 == SourceBitmap)
+ SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
+ if (0 == SourceBitmap)
{
- SURFACE_UnlockSurface(bitmap);
+ DPRINT1("Error : Could not create a DIBSection.\n");
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
- SourceSurf = EngLockSurface((HSURF)SourceBitmap);
- if (NULL == SourceSurf)
- {
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
+ RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ bmi->bmiHeader.biHeight,
+ bmi->bmiHeader.biBitCount));
- // Use hDIBPalette if it exists
- if (bitmap->hDIBPalette)
- {
- DDB_Palette = bitmap->hDIBPalette;
- }
- else
- {
- // Destination palette obtained from the hDC
- DDB_Palette = DC->ppdev->devinfo.hpalDefault;
- }
-
- ppalDDB = PALETTE_LockPalette(DDB_Palette);
- if (NULL == ppalDDB)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- // Source palette obtained from the BITMAPINFO
- DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type);
- if (NULL == DIB_Palette)
- {
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
- SURFACE_UnlockSurface(bitmap);
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return 0;
- }
-
- ppalDIB = PALETTE_LockPalette(DIB_Palette);
-
- /* Initialize XLATEOBJ for color translation */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
+ psurfDst = SURFACE_LockSurface(hBitmap);
+ psurfSrc = SURFACE_LockSurface(SourceBitmap);
- // Zero point
- ZeroPoint.x = 0;
- ZeroPoint.y = 0;
+ if(!(psurfSrc && psurfDst))
+ {
+ DPRINT1("Error, could not lock surfaces\n");
+ goto cleanup;
+ }
- // Determine destination rectangle
- DestRect.left = 0;
- DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines;
- DestRect.right = SourceSize.cx;
- DestRect.bottom = DestRect.top + ScanLines;
+ rcDst.top = bmi->bmiHeader.biHeight < 0 ?
+ abs(bmi->bmiHeader.biHeight) - (ScanLines + StartScan) : StartScan;
+ rcDst.left = 0;
+ rcDst.bottom = rcDst.top + ScanLines;
+ rcDst.right = psurfDst->SurfObj.sizlBitmap.cx;
- copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint);
+ ptSrc.x = 0;
+ ptSrc.y = 0;
- // If it succeeded, return number of scanlines copies
- if (copyBitsResult == TRUE)
- {
- result = SourceSize.cy;
-// or
-// result = abs(bmi->bmiHeader.biHeight) - StartScan;
- }
+ EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, psurfDst->ppal, 0, 0, 0);
- // Clean up
- EXLATEOBJ_vCleanup(&exlo);
- PALETTE_UnlockPalette(ppalDIB);
- PALETTE_UnlockPalette(ppalDDB);
- PALETTE_FreePaletteByHandle(DIB_Palette);
- EngUnlockSurface(SourceSurf);
- EngDeleteSurface((HSURF)SourceBitmap);
+ result = IntEngCopyBits(&psurfDst->SurfObj,
+ &psurfSrc->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDst,
+ &ptSrc);
+ if(result)
+ result = ScanLines;
-// if (ColorUse == DIB_PAL_COLORS)
-// WinFree((LPSTR)lpRGB);
+ EXLATEOBJ_vCleanup(&exlo);
- SURFACE_UnlockSurface(bitmap);
+cleanup:
+ if(psurfSrc)
+ {
+ SURFACE_UnlockSurface(psurfSrc);
+ }
+ if(psurfDst)
+ {
+ SURFACE_UnlockSurface(psurfDst);
+ }
+ GreDeleteObject(SourceBitmap);
return result;
}
PDC Dc;
INT Ret;
NTSTATUS Status = STATUS_SUCCESS;
- UINT cjBits;
if (!Bits) return 0;
_SEH2_TRY
- { // FYI: We converted from CORE in gdi.
- ProbeForRead(bmi, sizeof(BITMAPINFO), 1);
- cjBits = bmi->bmiHeader.biBitCount * bmi->bmiHeader.biPlanes * bmi->bmiHeader.biWidth;
- cjBits = ((cjBits + 31) & ~31) / 8;
- cjBits *= ScanLines;
- ProbeForRead(Bits, cjBits, 1);
+ {
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1);
+ ProbeForRead(Bits,
+ DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ ScanLines,
+ bmi->bmiHeader.biBitCount),
+ 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
INT DIBWidth;
SIZEL SourceSize;
EXLATEOBJ exlo;
- PPALETTE ppalDDB = NULL, ppalDIB = NULL;
- HPALETTE hpalDDB, hpalDIB = NULL;
- ULONG DIBPaletteType;
+ PPALETTE ppalDIB = NULL;
+ HPALETTE hpalDIB = NULL;
if (!Bits) return 0;
_SEH2_TRY
{
- ProbeForRead(bmi, cjMaxInfo , 1);
+ ProbeForRead(bmi, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
return 0;
}
- /* Use destination palette obtained from the DC by default */
- hpalDDB = pDC->ppdev->devinfo.hpalDefault;
-
- /* Try to use hDIBPalette if it exists */
pSurf = pDC->dclevel.pSurface;
- if (pSurf && pSurf->hDIBPalette)
- {
- hpalDDB = pSurf->hDIBPalette;
- }
pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
SourceSize.cx = bmi->bmiHeader.biWidth;
SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
+ DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
hSourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
- BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
+ BitmapFormat(bmi->bmiHeader.biBitCount,
+ bmi->bmiHeader.biCompression),
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
(PVOID) Bits);
if (!hSourceBitmap)
goto Exit;
}
- /* Obtain destination palette */
- ppalDDB = PALETTE_LockPalette(hpalDDB);
- if (!ppalDDB)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- Status = STATUS_UNSUCCESSFUL;
- goto Exit;
- }
+ ASSERT(pSurf->ppal);
/* Create a palette for the DIB */
- hpalDIB = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
+ hpalDIB = BuildDIBPalette(bmi);
if (!hpalDIB)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
/* Lock the DIB palette */
ppalDIB = PALETTE_LockPalette(hpalDIB);
- if (!ppalDDB)
+ if (!ppalDIB)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
Status = STATUS_UNSUCCESSFUL;
}
/* Initialize EXLATEOBJ */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, ppalDIB, pSurf->ppal, 0, 0, 0);
/* Copy the bits */
DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n",
}
if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
- if (ppalDDB) PALETTE_UnlockPalette(ppalDDB);
if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
UINT MaxBits,
UINT MaxInfo)
{
- PDC Dc;
- SURFACE *psurf = NULL;
- HBITMAP hDestBitmap = NULL;
- HPALETTE hSourcePalette = NULL;
- HPALETTE hDestPalette = NULL;
- PPALETTE ppalSrc = NULL;
- PPALETTE ppalDst = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- ULONG Result = 0;
- BOOL bPaletteMatch = FALSE;
- PBYTE ChkBits = Bits;
- PVOID ColorPtr;
- RGBQUAD *rgbQuads;
- ULONG DestPaletteType;
- ULONG Index;
+ BITMAPCOREINFO* pbmci = NULL;
+ PSURFACE psurf = NULL;
+ PDC pDC;
+ LONG width, height;
+ WORD planes, bpp;
+ DWORD compr, size ;
+ int i, bitmap_type;
+ RGBTRIPLE* rgbTriples;
+ RGBQUAD* rgbQuads;
+ VOID* colorPtr;
+ NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap)
return 0;
- // if ScanLines == 0, no need to copy Bits.
- if (!ScanLines)
- ChkBits = NULL;
-
_SEH2_TRY
{
- ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1);
-
- ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
- if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
+ /* Probe for read and write */
+ ProbeForRead(Info, MaxInfo, 1);
+ ProbeForWrite(Info, MaxInfo, 1);
+ if (Bits) ProbeForWrite(Bits, MaxBits, 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
- Dc = DC_LockDc(hDC);
- if (Dc == NULL) return 0;
- if (Dc->dctype == DC_TYPE_INFO)
+ colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize;
+ rgbTriples = colorPtr;
+ rgbQuads = colorPtr;
+
+ bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader,
+ &width,
+ &height,
+ &planes,
+ &bpp,
+ &compr,
+ &size);
+ if(bitmap_type == -1)
+ {
+ DPRINT("Wrong bitmap format\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ else if(bitmap_type == 0)
+ {
+ /* We need a BITMAPINFO to create a DIB, but we have to fill
+ * the BITMAPCOREINFO we're provided */
+ pbmci = (BITMAPCOREINFO*)Info;
+ Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage);
+ if(Info == NULL)
+ {
+ DPRINT1("Error, could not convert the BITMAPCOREINFO!\n");
+ return 0;
+ }
+ rgbQuads = Info->bmiColors;
+ }
+
+ pDC = DC_LockDc(hDC);
+ if (pDC == NULL || pDC->dctype == DC_TYPE_INFO)
{
- DC_UnlockDc(Dc);
- return 0;
+ ScanLines = 0;
+ goto done;
}
- DC_UnlockDc(Dc);
/* Get a pointer to the source bitmap object */
psurf = SURFACE_LockSurface(hBitmap);
if (psurf == NULL)
- return 0;
-
- hSourcePalette = psurf->hDIBPalette;
- if (!hSourcePalette)
- {
- hSourcePalette = pPrimarySurface->devinfo.hpalDefault;
- }
-
- ColorPtr = ((PBYTE)Info + Info->bmiHeader.biSize);
- rgbQuads = (RGBQUAD *)ColorPtr;
-
- /* Copy palette information
- * Always create a palette for 15 & 16 bit. */
- if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) &&
- Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) ||
- !ChkBits)
{
- hDestPalette = hSourcePalette;
- bPaletteMatch = TRUE;
- }
- else
- hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
-
- ppalSrc = PALETTE_LockPalette(hSourcePalette);
- /* FIXME - ppalSrc can be NULL!!! Don't assert here! */
- ASSERT(ppalSrc);
-
- if (!bPaletteMatch)
- {
- ppalDst = PALETTE_LockPalette(hDestPalette);
- /* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */
- DPRINT("ppalDst : %p\n", ppalDst);
- ASSERT(ppalDst);
- }
- else
- {
- ppalDst = ppalSrc;
- }
-
- /* Copy palette. */
- /* FIXME: This is largely incomplete. ATM no Core!*/
- switch (Info->bmiHeader.biBitCount)
- {
- case 1:
- case 4:
- case 8:
- Info->bmiHeader.biClrUsed = 0;
- if (psurf->hSecure &&
- BitsPerFormat(psurf->SurfObj.iBitmapFormat) == Info->bmiHeader.biBitCount)
- {
- if (Usage == DIB_RGB_COLORS)
- {
- if (ppalDst->NumColors != 1 << Info->bmiHeader.biBitCount)
- Info->bmiHeader.biClrUsed = ppalDst->NumColors;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
- Index++)
- {
- rgbQuads[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
- rgbQuads[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
- rgbQuads[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
- rgbQuads[Index].rgbReserved = 0;
- }
- }
- else
- {
- PWORD Ptr = ColorPtr;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
+ ScanLines = 0;
+ goto done;
+ }
+
+ /* Fill in the structure */
+ switch(bpp)
+ {
+ case 0: /* Only info */
+ if(pbmci)
+ {
+ pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
+ pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;
+ pbmci->bmciHeader.bcPlanes = 1;
+ pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ }
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
+ psurf->SurfObj.sizlBitmap.cy;;
+ Info->bmiHeader.biPlanes = 1;
+ Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth,
+ Info->bmiHeader.biHeight,
+ Info->bmiHeader.biBitCount);
+ if(psurf->hSecure)
+ {
+ switch(Info->bmiHeader.biBitCount)
+ {
+ case 16:
+ case 32:
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ break;
+ default:
+ Info->bmiHeader.biCompression = BI_RGB;
+ break;
+ }
+ }
+ else if(Info->bmiHeader.biBitCount > 8)
+ {
+ Info->bmiHeader.biCompression = BI_BITFIELDS;
+ }
+ else
+ {
+ Info->bmiHeader.biCompression = BI_RGB;
+ }
+ Info->bmiHeader.biXPelsPerMeter = 0;
+ Info->bmiHeader.biYPelsPerMeter = 0;
+ Info->bmiHeader.biClrUsed = 0;
+ Info->bmiHeader.biClrImportant = 0;
+ ScanLines = abs(Info->bmiHeader.biHeight);
+ goto done;
+
+ case 1:
+ case 4:
+ case 8:
+ Info->bmiHeader.biClrUsed = 0;
+
+ /* If the bitmap if a DIB section and has the same format than what
+ * we're asked, go ahead! */
+ if((psurf->hSecure) &&
+ (BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
+ {
+ if(Usage == DIB_RGB_COLORS)
+ {
+ unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
+
+ if(pbmci)
+ {
+ for(i=0; i < colors; i++)
+ {
+ rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
+ }
+ if(colors != 1 << bpp) Info->bmiHeader.biClrUsed = colors;
+ for(i=0; i < colors; i++)
+ {
+ rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue;
+ }
+ }
+ else
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ }
+ else
+ {
+ if(Usage == DIB_PAL_COLORS)
+ {
+ for(i=0; i < 1 << bpp; i++)
+ {
+ if(pbmci) ((WORD*)rgbTriples)[i] = i;
+ ((WORD*)rgbQuads)[i] = i;
+ }
+ }
+ else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat)) {
+ /* For color DDBs in native depth (mono DDBs always have
+ a black/white palette):
+ Generate the color map from the selected palette */
+ PPALETTE pDcPal = PALETTE_LockPalette(pDC->dclevel.hpal);
+ if(!pDcPal)
+ {
+ ScanLines = 0 ;
+ goto done ;
+ }
+ for (i = 0; i < pDcPal->NumColors; i++) {
+ if (pbmci)
{
- Ptr[Index] = (WORD)Index;
+ rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed;
+ rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
}
- }
- }
- else
- {
- if (Usage == DIB_PAL_COLORS)
- {
- PWORD Ptr = ColorPtr;
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount);
- Index++)
- {
- Ptr[Index] = (WORD)Index;
- }
- }
- else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
- {
- for (Index = 0;
- Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
- Index++)
+
+ rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
+ rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
+ rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
+ rgbQuads[i].rgbReserved = 0;
+ }
+ PALETTE_UnlockPalette(pDcPal);
+ } else {
+ switch (bpp) {
+ case 1:
+ if (pbmci)
{
- Info->bmiColors[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
- Info->bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
- Info->bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
- Info->bmiColors[Index].rgbReserved = 0;
+ rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
+ rgbTriples[0].rgbtBlue = 0;
+ rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
+ rgbTriples[1].rgbtBlue = 0xff;
}
- }
- else
- {
- switch (Info->bmiHeader.biBitCount)
+ rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
+ rgbQuads[0].rgbBlue = 0;
+ rgbQuads[0].rgbReserved = 0;
+ rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
+ rgbQuads[1].rgbBlue = 0xff;
+ rgbQuads[1].rgbReserved = 0;
+ break;
+
+ case 4:
+ if (pbmci)
+ RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples));
+ RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads));
+
+ break;
+
+ case 8:
{
- case 1:
- rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
- rgbQuads[0].rgbReserved = 0;
- rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
- rgbQuads[1].rgbReserved = 0;
- break;
- case 4:
- RtlCopyMemory(ColorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
- break;
- case 8:
+ INT r, g, b;
+ RGBQUAD *color;
+ if (pbmci)
{
- INT r, g, b;
- RGBQUAD *color;
-
- RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
- RtlCopyMemory(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
- color = rgbQuads + 10;
- for (r = 0; r <= 5; r++) /* FIXME */
- for (g = 0; g <= 5; g++)
- for (b = 0; b <= 5; b++)
- {
- color->rgbRed = (r * 0xff) / 5;
- color->rgbGreen = (g * 0xff) / 5;
- color->rgbBlue = (b * 0xff) / 5;
- color->rgbReserved = 0;
+ RGBTRIPLE *colorTriple;
+
+ RtlCopyMemory(rgbTriples, DefLogPaletteTriples,
+ 10 * sizeof(RGBTRIPLE));
+ RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10,
+ 10 * sizeof(RGBTRIPLE));
+ colorTriple = rgbTriples + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ {
+ for(g = 0; g <= 5; g++)
+ {
+ for(b = 0; b <= 5; b++)
+ {
+ colorTriple->rgbtRed = (r * 0xff) / 5;
+ colorTriple->rgbtGreen = (g * 0xff) / 5;
+ colorTriple->rgbtBlue = (b * 0xff) / 5;
color++;
}
+ }
+ }
}
- break;
+ memcpy(rgbQuads, DefLogPaletteQuads,
+ 10 * sizeof(RGBQUAD));
+ memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
+ 10 * sizeof(RGBQUAD));
+ color = rgbQuads + 10;
+ for(r = 0; r <= 5; r++) /* FIXME */
+ {
+ for(g = 0; g <= 5; g++)
+ {
+ for(b = 0; b <= 5; b++)
+ {
+ color->rgbRed = (r * 0xff) / 5;
+ color->rgbGreen = (g * 0xff) / 5;
+ color->rgbBlue = (b * 0xff) / 5;
+ color->rgbReserved = 0;
+ color++;
+ }
+ }
+ }
}
}
}
+ }
+ break;
- case 15:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
- {
- ((PDWORD)Info->bmiColors)[0] = 0x7c00;
- ((PDWORD)Info->bmiColors)[1] = 0x03e0;
- ((PDWORD)Info->bmiColors)[2] = 0x001f;
- }
- break;
+ case 15:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ ((PDWORD)Info->bmiColors)[0] = 0x7c00;
+ ((PDWORD)Info->bmiColors)[1] = 0x03e0;
+ ((PDWORD)Info->bmiColors)[2] = 0x001f;
+ }
+ break;
- case 16:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ case 16:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
+ else
{
((PDWORD)Info->bmiColors)[0] = 0xf800;
((PDWORD)Info->bmiColors)[1] = 0x07e0;
((PDWORD)Info->bmiColors)[2] = 0x001f;
}
- break;
+ }
+ break;
- case 24:
- case 32:
- if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ case 24:
+ case 32:
+ if (Info->bmiHeader.biCompression == BI_BITFIELDS)
+ {
+ if (psurf->hSecure)
+ {
+ ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask;
+ ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask;
+ ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask;
+ }
+ else
{
((PDWORD)Info->bmiColors)[0] = 0xff0000;
((PDWORD)Info->bmiColors)[1] = 0x00ff00;
((PDWORD)Info->bmiColors)[2] = 0x0000ff;
}
- break;
- }
-
- if (!bPaletteMatch)
- PALETTE_UnlockPalette(ppalDst);
-
- /* fill out the BITMAPINFO struct */
- if (!ChkBits)
- { // Core or not to Core? We have converted from Core in Gdi~ so?
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
- coreheader->bcWidth = psurf->SurfObj.sizlBitmap.cx;
- coreheader->bcPlanes = 1;
- coreheader->bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- coreheader->bcHeight = psurf->SurfObj.sizlBitmap.cy;
- if (psurf->SurfObj.lDelta > 0)
- coreheader->bcHeight = -coreheader->bcHeight;
- }
-
- if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
- {
- Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
- Info->bmiHeader.biHeight = psurf->SurfObj.sizlBitmap.cy;
- Info->bmiHeader.biPlanes = 1;
- Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
- switch (psurf->SurfObj.iBitmapFormat)
- {
- /* FIXME: What about BI_BITFIELDS? */
- case BMF_1BPP:
- case BMF_4BPP:
- case BMF_8BPP:
- case BMF_16BPP:
- case BMF_24BPP:
- case BMF_32BPP:
- Info->bmiHeader.biCompression = BI_RGB;
- break;
- case BMF_4RLE:
- Info->bmiHeader.biCompression = BI_RLE4;
- break;
- case BMF_8RLE:
- Info->bmiHeader.biCompression = BI_RLE8;
- break;
- case BMF_JPEG:
- Info->bmiHeader.biCompression = BI_JPEG;
- break;
- case BMF_PNG:
- Info->bmiHeader.biCompression = BI_PNG;
- break;
- }
- /* Image size has to be calculated */
- Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth,
- Info->bmiHeader.biBitCount) * Info->bmiHeader.biHeight;
- Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
- Info->bmiHeader.biClrUsed = 0;
- Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
- /* Report negtive height for top-down bitmaps. */
- if (psurf->SurfObj.lDelta > 0)
- Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
}
- Result = psurf->SurfObj.sizlBitmap.cy;
- }
- else
- {
- SIZEL DestSize;
- POINTL SourcePoint;
-
-//
-// If we have a good dib pointer, why not just copy bits from there w/o XLATE'ing them.
-//
- /* Create the destination bitmap too for the copy operation */
- if (StartScan > psurf->SurfObj.sizlBitmap.cy)
+ break;
+ }
+ Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
+
+ if(Bits && ScanLines)
+ {
+ /* Create a DIBSECTION, blt it, profit */
+ PVOID pDIBits ;
+ HBITMAP hBmpDest;
+ PSURFACE psurfDest;
+ EXLATEOBJ exlo;
+ RECT rcDest;
+ POINTL srcPoint;
+ BOOL ret ;
+
+ if (StartScan > psurf->SurfObj.sizlBitmap.cy)
{
- goto cleanup;
+ ScanLines = 0;
+ goto done;
}
else
{
ScanLines = min(ScanLines, psurf->SurfObj.sizlBitmap.cy - StartScan);
- DestSize.cx = psurf->SurfObj.sizlBitmap.cx;
- DestSize.cy = ScanLines;
-
- hDestBitmap = NULL;
-
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
- BitmapFormat(coreheader->bcBitCount, BI_RGB),
- 0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
-
- if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
- {
- Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx,
- Info->bmiHeader.biBitCount) * DestSize.cy;
-
- hDestBitmap = EngCreateBitmap(DestSize,
- DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount),
- BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
- 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
- Bits);
- }
-
- if (hDestBitmap == NULL)
- goto cleanup;
- }
-
- if (NT_SUCCESS(Status))
- {
- EXLATEOBJ exlo;
- SURFOBJ *DestSurfObj;
- RECTL DestRect;
-
- EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0);
-
- SourcePoint.x = 0;
- SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
-
- /* Determine destination rectangle */
- DestRect.top = 0;
- DestRect.left = 0;
- DestRect.right = DestSize.cx;
- DestRect.bottom = DestSize.cy;
-
- DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
-
- if (IntEngCopyBits(DestSurfObj,
- &psurf->SurfObj,
- NULL,
- &exlo.xlo,
- &DestRect,
- &SourcePoint))
- {
- DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan);
- Result = ScanLines;
- }
-
- EXLATEOBJ_vCleanup(&exlo);
- EngUnlockSurface(DestSurfObj);
- }
- }
-cleanup:
- PALETTE_UnlockPalette(ppalSrc);
-
- if (hDestBitmap != NULL)
- EngDeleteSurface((HSURF)hDestBitmap);
-
- if (hDestPalette != NULL && bPaletteMatch == FALSE)
- PALETTE_FreePaletteByHandle(hDestPalette);
-
- SURFACE_UnlockSurface(psurf);
-
- DPRINT("leaving NtGdiGetDIBitsInternal\n");
-
- return Result;
+ }
+
+ /* Fixup values */
+ Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
+ Info->bmiHeader.biHeight = height < 0 ?
+ -ScanLines : ScanLines;
+ /* Create the DIB */
+ hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0);
+ /* Restore them */
+ Info->bmiHeader.biWidth = width;
+ Info->bmiHeader.biHeight = height;
+
+ if(!hBmpDest)
+ {
+ DPRINT1("Unable to create a DIB Section!\n");
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ ScanLines = 0;
+ goto done ;
+ }
+
+ psurfDest = SURFACE_LockSurface(hBmpDest);
+
+ rcDest.left = 0;
+ rcDest.top = 0;
+ rcDest.bottom = ScanLines;
+ rcDest.right = psurf->SurfObj.sizlBitmap.cx;
+
+ srcPoint.x = 0;
+ srcPoint.y = height < 0 ?
+ psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines) : StartScan;
+
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0, 0, 0);
+
+ ret = IntEngCopyBits(&psurfDest->SurfObj,
+ &psurf->SurfObj,
+ NULL,
+ &exlo.xlo,
+ &rcDest,
+ &srcPoint);
+
+ if(!ret)
+ ScanLines = 0;
+ else
+ {
+ Status = STATUS_SUCCESS;
+ _SEH2_TRY
+ {
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to copy bits to the user provided pointer\n");
+ ScanLines = 0;
+ }
+ }
+
+ GreDeleteObject(hBmpDest);
+ EXLATEOBJ_vCleanup(&exlo);
+ }
+ else ScanLines = abs(height);
+
+done:
+
+ if(pDC) DC_UnlockDc(pDC);
+ if(psurf) SURFACE_UnlockSurface(psurf);
+ if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci);
+
+ return ScanLines;
}
+
INT
APIENTRY
NtGdiStretchDIBitsInternal(
UINT cjMaxBits,
HANDLE hcmXform)
{
- HBITMAP hBitmap, hOldBitmap = NULL;
- HDC hdcMem;
- HPALETTE hPal = NULL;
- PDC pDC;
- BOOL Hit = FALSE;
+ PDC pdc;
+ INT ret = 0;
+ LONG height;
+ LONG width;
+ WORD planes, bpp;
+ DWORD compr, size;
+ HBITMAP hBitmap;
+ BOOL fastpath = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits ;
if (!Bits || !BitsInfo)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
- }
+
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return 0;
+ }
+
+ if (!(pdc = DC_LockDc(hDC)))
+ {
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
_SEH2_TRY
{
ProbeForRead(BitsInfo, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1);
+ if (DIB_GetBitmapInfo( &BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
+ {
+ DPRINT1("Invalid bitmap\n");
+ Status = STATUS_INVALID_PARAMETER;
+ }
+ RtlCopyMemory(safeBits, Bits, cjMaxBits);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Hit = TRUE;
+ Status = _SEH2_GetExceptionCode();
}
_SEH2_END
- if (Hit)
- {
- DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits);
- return 0;
- }
-
- hdcMem = NtGdiCreateCompatibleDC(hDC);
- if (hdcMem == NULL)
+ if(!NT_SUCCESS(Status))
{
- DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
- return 0;
+ DPRINT1("Error, failed to read the DIB bits\n");
+ goto cleanup;
}
- hBitmap = NtGdiCreateCompatibleBitmap(hDC,
- abs(BitsInfo->bmiHeader.biWidth),
- abs(BitsInfo->bmiHeader.biHeight));
- if (hBitmap == NULL)
+ if (width < 0)
{
- DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n");
- DPRINT1("hDC : 0x%08x \n", hDC);
- DPRINT1("BitsInfo->bmiHeader.biWidth : 0x%08x \n", BitsInfo->bmiHeader.biWidth);
- DPRINT1("BitsInfo->bmiHeader.biHeight : 0x%08x \n", BitsInfo->bmiHeader.biHeight);
+ DPRINT1("Bitmap has a negative width\n");
return 0;
}
- /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
+ hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP);
- if (Usage == DIB_PAL_COLORS)
+ if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 &&
+ DestWidth == SrcWidth && DestHeight == SrcHeight &&
+ compr == BI_RGB &&
+ ROP == SRCCOPY)
{
- hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE);
- hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
+ BITMAP bmp;
+ if (IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp))
+ {
+ if (bmp.bmBitsPixel == bpp &&
+ bmp.bmWidth == SrcWidth &&
+ bmp.bmHeight == SrcHeight &&
+ bmp.bmPlanes == planes)
+ fastpath = TRUE;
+ }
}
- if (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
- BitsInfo->bmiHeader.biCompression == BI_RLE8)
+ if (fastpath)
{
- /* copy existing bitmap from destination dc */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
- else
- NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
- ROP, 0);
+ /* fast path */
+ DPRINT1("using fast path\n");
+ ret = IntSetDIBits( pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
}
-
- pDC = DC_LockDc(hdcMem);
- if (pDC != NULL)
+ else
{
- /* Note BitsInfo->bmiHeader.biHeight is the number of scanline,
- * if it negitve we getting to many scanline for scanline is UINT not
- * a INT, so we need make the negtive value to positve and that make the
- * count correct for negtive bitmap, TODO : we need testcase for this api */
- IntSetDIBits(pDC, hBitmap, 0, abs(BitsInfo->bmiHeader.biHeight), Bits,
- BitsInfo, Usage);
-
- DC_UnlockDc(pDC);
+ /* slow path - need to use StretchBlt */
+ HBITMAP hOldBitmap;
+ HDC hdcMem;
+ PVOID pvBits;
+
+ hdcMem = NtGdiCreateCompatibleDC( hDC );
+ hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
+ if(!hBitmap)
+ {
+ DPRINT1("Error, failed to create a DIB section\n");
+ NtGdiDeleteObjectApp(hdcMem);
+ goto cleanup;
+ }
+ RtlCopyMemory(pvBits, safeBits, cjMaxBits);
+ hOldBitmap = NtGdiSelectBitmap( hdcMem, hBitmap );
+
+ /* Origin for DIBitmap may be bottom left (positive biHeight) or top
+ left (negative biHeight) */
+ ret = NtGdiStretchBlt( hDC, XDest, YDest, DestWidth, DestHeight,
+ hdcMem, XSrc, abs(height) - SrcHeight - YSrc,
+ SrcWidth, SrcHeight, ROP, 0 );
+
+ if(ret)
+ ret = SrcHeight;
+ NtGdiSelectBitmap( hdcMem, hOldBitmap );
+ NtGdiDeleteObjectApp( hdcMem );
+ GreDeleteObject( hBitmap );
}
-
-
- /* Origin for DIBitmap may be bottom left (positive biHeight) or top
- left (negative biHeight) */
- if (SrcWidth == DestWidth && SrcHeight == DestHeight)
- NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- ROP, 0, 0);
- else
- NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
- hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
- SrcWidth, SrcHeight, ROP, 0);
-
- /* cleanup */
- if (hPal)
- GdiSelectPalette(hdcMem, hPal, FALSE);
-
- if (hOldBitmap)
- NtGdiSelectBitmap(hdcMem, hOldBitmap);
-
- NtGdiDeleteObjectApp(hdcMem);
-
- GreDeleteObject(hBitmap);
-
- return SrcHeight;
+cleanup:
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ DC_UnlockDc(pdc);
+ return ret;
}
else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
else
{
- if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
- {
- const RGBQUAD *rgb = data->bmiColors;
- DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
-
- // Check if the first color of the colormap is black
- if ((col == RGB(0, 0, 0)))
- {
- rgb++;
- col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
+ const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
+ DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
- // If the second color is white, create a monochrome bitmap
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ // Check if the first color of the colormap is black
+ if ((col == RGB(0, 0, 0)))
{
- RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
- DWORD col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
+ rgb++;
+ col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
- if ((col == RGB(0,0,0)))
- {
- rgb++;
- col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
- fColor = (col != RGB(0xff,0xff,0xff));
- }
- else fColor = TRUE;
- }
- else
- {
- DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize);
- return 0;
+ // If the second color is white, create a monochrome bitmap
+ fColor = (col != RGB(0xff,0xff,0xff));
}
+ else fColor = TRUE;
}
// Now create the bitmap
}
else
{
- handle = IntGdiCreateBitmap(width,
- height,
- 1,
- 1,
- NULL);
+ handle = GreCreateBitmap(width,
+ height,
+ 1,
+ 1,
+ NULL);
}
if (height < 0)
IN UINT cjMaxBits,
IN FLONG fl,
IN HANDLE hcmXform)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits = NULL;
+ HBITMAP hbmResult = NULL;
+
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+ }
+
+ _SEH2_TRY
+ {
+ if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ ProbeForRead(pjInit, cjMaxBits, 1);
+ RtlCopyMemory(safeBits, pjInit, cjMaxBits);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ goto cleanup;
+ }
+
+ hbmResult = GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ safeBits,
+ pbmi,
+ iUsage,
+ fl,
+ hcmXform);
+
+cleanup:
+ if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
+ return hbmResult;
+}
+
+HBITMAP
+FASTCALL
+GreCreateDIBitmapInternal(
+ IN HDC hDc,
+ IN INT cx,
+ IN INT cy,
+ IN DWORD fInit,
+ IN OPTIONAL LPBYTE pjInit,
+ IN OPTIONAL PBITMAPINFO pbmi,
+ IN DWORD iUsage,
+ IN FLONG fl,
+ IN HANDLE hcmXform)
{
PDC Dc;
HBITMAP Bmp;
- UINT bpp;
+ WORD bpp;
+ HDC hdcDest;
- if (!hDc) // CreateBitmap
+ if (!hDc) /* 1bpp monochrome bitmap */
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
- hDc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
- if (!hDc)
+ hdcDest = NtGdiCreateCompatibleDC(0);
+ if(!hdcDest)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
-
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- NtGdiDeleteObjectApp(hDc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
- bpp = 1;
- Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+ }
+ else
+ {
+ hdcDest = hDc;
+ }
- DC_UnlockDc(Dc);
- NtGdiDeleteObjectApp(hDc);
+ Dc = DC_LockDc(hdcDest);
+ if (!Dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return NULL;
}
- else // CreateCompatibleBitmap
+ /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
+ * if bpp != 1 and ignore the real value that was passed */
+ if (pbmi)
+ bpp = pbmi->bmiHeader.biBitCount;
+ else
+ bpp = 0;
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
+ DC_UnlockDc(Dc);
+
+ if(!hDc)
{
- Dc = DC_LockDc(hDc);
- if (!Dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return NULL;
- }
- /* pbmi == null
- First create an un-initialised bitmap. The depth of the bitmap
- should match that of the hdc and not that supplied in bmih.
- */
- if (pbmi)
- bpp = pbmi->bmiHeader.biBitCount;
- else
- {
- if (Dc->dctype != DC_TYPE_MEMORY)
- bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL);
- else
- {
- DIBSECTION dibs;
- INT Count;
- SURFACE *psurf = Dc->dclevel.pSurface;
- Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
- if (!Count)
- bpp = 1;
- else
- {
- if (Count == sizeof(BITMAP))
- /* A device-dependent bitmap is selected in the DC */
- bpp = dibs.dsBm.bmBitsPixel;
- else
- /* A DIB section is selected in the DC */
- bpp = dibs.dsBmih.biBitCount;
- }
- }
- }
- Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
- DC_UnlockDc(Dc);
+ NtGdiDeleteObjectApp(hdcDest);
}
return Bmp;
}
IN HDC hDC,
IN OPTIONAL HANDLE hSection,
IN DWORD dwOffset,
- IN LPBITMAPINFO bmi,
+ IN BITMAPINFO* bmi,
IN DWORD Usage,
IN UINT cjHeader,
IN FLONG fl,
HBITMAP hbitmap = 0;
DC *dc;
BOOL bDesktopDC = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
if (!bmi) return hbitmap; // Make sure.
+ _SEH2_TRY
+ {
+ ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
+ ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
+ ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, Usage), 1);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return NULL;
+ }
+
// If the reference hdc is null, take the desktop dc
if (hDC == 0)
{
if ((dc = DC_LockDc(hDC)))
{
hbitmap = DIB_CreateDIBSection(dc,
- (BITMAPINFO*)bmi,
+ bmi,
Usage,
Bits,
hSection,
APIENTRY
DIB_CreateDIBSection(
PDC dc,
- BITMAPINFO *bmi,
+ CONST BITMAPINFO *bmi,
UINT usage,
LPVOID *bits,
HANDLE section,
HBITMAP res = 0;
SURFACE *bmp = NULL;
void *mapBits = NULL;
+ HPALETTE hpal ;
// Fill BITMAP32 structure with DIB data
- BITMAPINFOHEADER *bi = &bmi->bmiHeader;
+ CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
INT effHeight;
ULONG totalSize;
BITMAP bm;
SIZEL Size;
- RGBQUAD *lpRGB;
HANDLE hSecure;
- DWORD dsBitfields[3] = {0};
- ULONG ColorCount;
DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
bm.bmType = 0;
bm.bmWidth = bi->biWidth;
bm.bmHeight = effHeight;
- bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
+ bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
bm.bmPlanes = bi->biPlanes;
bm.bmBitsPixel = bi->biBitCount;
{
offset = 0;
bm.bmBits = EngAllocUserMem(totalSize, 0);
+ if(!bm.bmBits) goto cleanup;
}
// hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE);
if (usage == DIB_PAL_COLORS)
{
- lpRGB = DIB_MapPaletteColors(dc, bmi);
- ColorCount = bi->biClrUsed;
- if (ColorCount == 0)
- {
- ColorCount = 1 << bi->biBitCount;
- }
+ if(dc)
+ {
+ PPALETTE pdcPal ;
+ pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
+ hpal = DIB_MapPaletteColors(pdcPal, bmi);
+ PALETTE_UnlockPalette(pdcPal);
+ }
+ else
+ {
+ /* For DIB Brushes */
+ DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
+ /* HACK */
+ hpal = (HPALETTE) 0xFFFFFFFF;
+ }
}
else
- {
- lpRGB = bmi->bmiColors;
- ColorCount = 1 << bi->biBitCount;
- }
-
- /* Set dsBitfields values */
- if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
- {
- dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0;
- }
- else if (bi->biCompression == BI_RGB)
- {
- switch (bi->biBitCount)
- {
- case 15:
- case 16:
- dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0x7c00;
- dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x03e0;
- dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x001f;
- break;
+ {
+ hpal = BuildDIBPalette(bmi);
+ }
- case 24:
- case 32:
- dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0xff0000;
- dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x00ff00;
- dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x0000ff;
- break;
- }
- }
- else
- {
- dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0];
- dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1];
- dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2];
- }
+ if(!hpal)
+ {
+ DPRINT1("Error : Could not create a palette for the DIB.\n");
+ goto cleanup;
+ }
// Create Device Dependent Bitmap and add DIB pointer
Size.cx = bm.bmWidth;
Size.cy = abs(bm.bmHeight);
- res = IntCreateBitmap(Size,
- bm.bmWidthBytes,
- BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
- BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
- (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
- bm.bmBits);
+ res = GreCreateBitmapEx(bm.bmWidth,
+ abs(bm.bmHeight),
+ bm.bmWidthBytes,
+ BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression),
+ BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
+ (bi->biHeight < 0 ? BMF_TOPDOWN : 0),
+ bi->biSizeImage,
+ bm.bmBits,
+ 0);
if (!res)
{
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
- return NULL;
+ goto cleanup;
}
bmp = SURFACE_LockSurface(res);
if (NULL == bmp)
{
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- GreDeleteObject(bmp);
- return NULL;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ goto cleanup;
}
/* WINE NOTE: WINE makes use of a colormap, which is a color translation
table between the DIB and the X physical device. Obviously,
this is left out of the ReactOS implementation. Instead,
we call NtGdiSetDIBColorTable. */
- if (bi->biBitCount <= 8)
- {
- bi->biClrUsed = 1 << bi->biBitCount;
- }
- else
- {
- bi->biClrUsed = 0;
- }
-
bmp->hDIBSection = section;
bmp->hSecure = hSecure;
bmp->dwOffset = offset;
- bmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
- bmp->dsBitfields[0] = dsBitfields[0];
- bmp->dsBitfields[1] = dsBitfields[1];
- bmp->dsBitfields[2] = dsBitfields[2];
- bmp->biClrUsed = bi->biClrUsed;
+ bmp->flags = API_BITMAP;
bmp->biClrImportant = bi->biClrImportant;
- if (bi->biClrUsed != 0)
- {
- bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB);
- }
- else
- {
- bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL,
- dsBitfields[0],
- dsBitfields[1],
- dsBitfields[2]);
- }
+ /* HACK */
+ if(hpal != (HPALETTE)0xFFFFFFFF)
+ {
+ bmp->ppal = PALETTE_ShareLockPalette(hpal);
+ /* Lazy delete hpal, it will be freed at surface release */
+ GreDeleteObject(hpal);
+ }
// Clean up in case of errors
+cleanup:
if (!res || !bmp || !bm.bmBits)
{
DPRINT("got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits);
}
}
- if (lpRGB != bmi->bmiColors)
- {
- ExFreePoolWithTag(lpRGB, TAG_COLORMAP);
- }
-
if (bmp)
{
SURFACE_UnlockSurface(bmp);
}
/***********************************************************************
- * DIB_GetDIBWidthBytes
+ * DIB_GetBitmapInfo
*
- * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
- * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
- * 11/16/1999 (RJJ) lifted from wine
+ * Get the info from a bitmap header.
+ * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
*/
-INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
+int
+FASTCALL
+DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+ LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
{
- return ((width * depth + 31) & ~31) >> 3;
+ if (header->biSize == sizeof(BITMAPCOREHEADER))
+ {
+ const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
+ *width = core->bcWidth;
+ *height = core->bcHeight;
+ *planes = core->bcPlanes;
+ *bpp = core->bcBitCount;
+ *compr = BI_RGB;
+ *size = 0;
+ return 0;
+ }
+ if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */
+ {
+ *width = header->biWidth;
+ *height = header->biHeight;
+ *planes = header->biPlanes;
+ *bpp = header->biBitCount;
+ *compr = header->biCompression;
+ *size = header->biSizeImage;
+ return 1;
+ }
+ DPRINT1("(%d): unknown/wrong size for header\n", header->biSize );
+ return -1;
}
/***********************************************************************
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
{
- return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height);
+ return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
}
/***********************************************************************
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
{
- int colors;
+ unsigned int colors, size, masks = 0;
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
- BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
+ const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
- return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
+ return sizeof(BITMAPCOREHEADER) + colors *
+ ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
}
else /* assume BITMAPINFOHEADER */
{
colors = info->bmiHeader.biClrUsed;
- if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount;
- return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
+ if (colors > 256) colors = 256;
+ if (!colors && (info->bmiHeader.biBitCount <= 8))
+ colors = 1 << info->bmiHeader.biBitCount;
+ if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
+ size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
+ return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
}
}
-RGBQUAD *
+HPALETTE
FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
{
- RGBQUAD *lpRGB;
+ PALETTEENTRY* ppalEntries;
ULONG nNumColors,i;
USHORT *lpIndex;
- PPALETTE palGDI;
-
- palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
-
- if (NULL == palGDI)
- {
- return NULL;
- }
+ HPALETTE hpal;
- if (palGDI->Mode != PAL_INDEXED)
+ if (!(ppal->flFlags & PAL_INDEXED))
{
- PALETTE_UnlockPalette(palGDI);
return NULL;
}
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
}
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
- if (lpRGB == NULL)
+ /* Don't have more colors than we need */
+ nNumColors = min(ppal->NumColors, nNumColors);
+
+ ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP);
+ if (ppalEntries == NULL)
{
- PALETTE_UnlockPalette(palGDI);
+ DPRINT1("Could not allocate palette entries\n");
return NULL;
}
- lpIndex = (USHORT *)&lpbmi->bmiColors[0];
+ lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
for (i = 0; i < nNumColors; i++)
{
- if (*lpIndex < palGDI->NumColors)
+ if (*lpIndex < ppal->NumColors)
{
- lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed;
- lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen;
- lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue;
+ ppalEntries[i] = ppal->IndexedColors[*lpIndex];
}
else
{
- lpRGB[i].rgbRed = 0;
- lpRGB[i].rgbGreen = 0;
- lpRGB[i].rgbBlue = 0;
+ ppalEntries[i].peRed = 0;
+ ppalEntries[i].peGreen = 0;
+ ppalEntries[i].peBlue = 0;
+ ppalEntries[i].peFlags = 0;
}
- lpRGB[i].rgbReserved = 0;
+
lpIndex++;
}
- PALETTE_UnlockPalette(palGDI);
- return lpRGB;
+ hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
+
+ ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
+
+ return hpal;
}
HPALETTE
FASTCALL
-BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
+BuildDIBPalette(CONST BITMAPINFO *bmi)
{
BYTE bits;
ULONG ColorCount;
- PALETTEENTRY *palEntries = NULL;
HPALETTE hPal;
- ULONG RedMask, GreenMask, BlueMask;
+ ULONG RedMask = 0, GreenMask = 0, BlueMask = 0;
+ PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
+ INT paletteType;
// Determine Bits Per Pixel
bits = bmi->bmiHeader.biBitCount;
// Determine paletteType from Bits Per Pixel
if (bits <= 8)
{
- *paletteType = PAL_INDEXED;
+ paletteType = PAL_INDEXED;
RedMask = GreenMask = BlueMask = 0;
}
else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
{
- *paletteType = PAL_BITFIELDS;
- RedMask = ((ULONG *)bmi->bmiColors)[0];
- GreenMask = ((ULONG *)bmi->bmiColors)[1];
- BlueMask = ((ULONG *)bmi->bmiColors)[2];
- }
- else if (bits < 24)
- {
- *paletteType = PAL_BITFIELDS;
- RedMask = 0x7c00;
- GreenMask = 0x03e0;
- BlueMask = 0x001f;
+ paletteType = PAL_BITFIELDS;
+ RedMask = pdwColors[0];
+ GreenMask = pdwColors[1];
+ BlueMask = pdwColors[2];
}
else
{
- *paletteType = PAL_BGR;
- RedMask = 0xff0000;
- GreenMask = 0x00ff00;
- BlueMask = 0x0000ff;
+ paletteType = PAL_BITFIELDS;
+ switch (bits)
+ {
+ case 15:
+ paletteType |= PAL_RGB16_555;
+ RedMask = 0x7C00;
+ GreenMask = 0x03E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 16:
+ paletteType |= PAL_RGB16_565;
+ RedMask = 0xF800;
+ GreenMask = 0x07E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 24:
+ case 32:
+ paletteType |= PAL_BGR;
+ RedMask = 0xFF0000;
+ GreenMask = 0x00FF00;
+ BlueMask = 0x0000FF;
+ break;
+ }
}
if (bmi->bmiHeader.biClrUsed == 0)
ColorCount = bmi->bmiHeader.biClrUsed;
}
- if (PAL_INDEXED == *paletteType)
+ if (PAL_INDEXED == paletteType)
{
- hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
+ hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
}
else
{
- hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
- (ULONG*) palEntries,
+ hPal = PALETTE_AllocPalette(paletteType, 0,
+ NULL,
RedMask, GreenMask, BlueMask);
}
return hPal;
}
+/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
+ * or does nothing if it's already a BITMAPINFO (or V4 or V5) */
+BITMAPINFO*
+FASTCALL
+DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage)
+{
+ CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi;
+ BITMAPINFO* pNewBmi ;
+ UINT numColors = 0, ColorsSize = 0;
+
+ if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi;
+ if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL;
+
+ if(pbmci->bmciHeader.bcBitCount <= 8)
+ {
+ numColors = 1 << pbmci->bmciHeader.bcBitCount;
+ if(Usage == DIB_PAL_COLORS)
+ {
+ ColorsSize = numColors * sizeof(WORD);
+ }
+ else
+ {
+ ColorsSize = numColors * sizeof(RGBQUAD);
+ }
+ }
+ else if (Usage == DIB_PAL_COLORS)
+ {
+ /* Invalid at high Res */
+ return NULL;
+ }
+
+ pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB);
+ if(!pNewBmi) return NULL;
+
+ RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize);
+
+ pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount;
+ pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth;
+ pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight;
+ pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes;
+ pNewBmi->bmiHeader.biCompression = BI_RGB ;
+ pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth,
+ pNewBmi->bmiHeader.biHeight,
+ pNewBmi->bmiHeader.biBitCount);
+
+ if(Usage == DIB_PAL_COLORS)
+ {
+ RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize);
+ }
+ else
+ {
+ UINT i;
+ for(i=0; i<numColors; i++)
+ {
+ pNewBmi->bmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed;
+ pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen;
+ pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue;
+ }
+ }
+
+ return pNewBmi ;
+}
+
+/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */
+VOID
+FASTCALL
+DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig)
+{
+ if(converted != orig)
+ ExFreePoolWithTag(converted, TAG_DIB);
+}
+
+
+
+
+
+
/* EOF */
} Rect, *PRect;
int FASTCALL IntFillRect(DC *dc, INT XLeft, INT YLeft, INT Width, INT Height, PBRUSH pbrush, BOOL Pen);
-int FASTCALL app_fill_rect(DC *dc, Rect r, PBRUSH pbrush, BOOL Pen);
+//int FASTCALL app_fill_rect(DC *dc, Rect r, PBRUSH pbrush, BOOL Pen);
static
POINT
INTERNAL_CALL
app_new_point(int x, int y)
{
- POINT p;
+ POINT p;
p.x = x;
p.y = y;
return p;
*
* The draw_arc algorithm is based on draw_ellipse, but unlike
* that algorithm is not symmetric in the general case, since
- * an angular portion is clipped from the shape.
+ * an angular portion is clipped from the shape.
* This clipping is performed by keeping track of two hypothetical
* lines joining the centre point to the enclosing rectangle,
* at the angles start_angle and end_angle, using a line-intersection
rise2 = p2.y - p0.y;
run2 = p2.x - p0.x;
- if (r.y <= p0.y) //
+ if (r.y <= p0.y) //
{
/* in top half of arc ellipse */
* between an outer and inner ellipse, and also the draw_arc and
* fill_arc operations which additionally clip drawing between
* a start_angle and an end_angle.
- *
+ *
*/
static
int
r1.height = r1.y+r1.height-r2.y;
r1.y = r2.y;
while (r1.height > 0) {
- result &= app_fill_arc_rect(g,
+ result &= app_fill_arc_rect(g,
rect(r1.x, r1.y, r1.width, 1),
p0, p1, p2, start_angle, end_angle, pbrush, FALSE);
r1.y += 1;
pdcattr = dc->pdcattr;
pbrush = BRUSH_LockBrush(pdcattr->hbrush);
- if (!pbrush)
+ if (!pbrush)
{
DPRINT1("FillArc Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
(dc->dclevel.flPath & DCPATH_CLOCKWISE) ? -Start : -End,
pbrush, Chord);
- BRUSH_UnlockBrush(pbrush);
+ BRUSH_UnlockBrush(pbrush);
return ret;
}
INT XLeft,
INT YLeft,
INT Width,
- INT Height,
+ INT Height,
PBRUSH pbrush)
{
return (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), pbrush);
INT Right,
INT Bottom,
INT Wellipse,
- INT Hellipse,
+ INT Hellipse,
PBRUSH pbrush)
{
Rect r;
270, 360, pbrush,FALSE);
app_fill_arc(dc, rect(r.x+r.width-rx-rx, r.y, rx+rx, ry+ry),
- 0, 90, pbrush,FALSE);
+ 0, 90, pbrush,FALSE);
}
if (Wellipse < r.width)
{
r = rect( Left, Top, abs(Right-Left), abs(Bottom-Top));
rx = Wellipse/2;
ry = Hellipse/2;
-
+
if (Wellipse > r.width)
{
if (Hellipse > r.height) // > W > H
app_draw_arc(dc, rect(r.x, r.y, Wellipse - 1, r.height - 1),
90, 270, pbrushPen, FALSE);
app_draw_arc(dc, rect(Right - Wellipse, r.y, Wellipse - 1, r.height - 1),
- 270, 90, pbrushPen, FALSE);
+ 270, 90, pbrushPen, FALSE);
}
else // < W < H
{
psurf,
&dc->eboFill.BrushObject,
Points,
- Count,
+ Count,
DestRect,
&BrushOrigin);
}
}
if (!PenWidth) PenWidth = 1;
- pbrush->ptPenWidth.x = PenWidth;
+ pbrush->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.right = Right;
RectBounds.top = Top;
RectBounds.bottom = Bottom;
-
+
IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
-
+
RectBounds.left += dc->ptlDCOrig.x;
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.top += dc->ptlDCOrig.y;
CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);
pFillBrushObj = BRUSH_LockBrush(pdcattr->hbrush);
- if (NULL == pFillBrushObj)
+ if (NULL == pFillBrushObj)
{
DPRINT1("FillEllipse Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return TRUE;
}
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
/* Perform the actual work */
switch (iFunc)
{
}
/* Cleanup and return */
+ DC_vFinishBlit(dc, NULL);
DC_UnlockDc(dc);
ExFreePool(pTemp);
pdcattr = dc->pdcattr;
- /* Do we rotate or shear? */
- if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE))
- {
-
- POINTL DestCoords[4];
- ULONG PolyCounts = 4;
- DestCoords[0].x = DestCoords[3].x = LeftRect;
- DestCoords[0].y = DestCoords[1].y = TopRect;
- DestCoords[1].x = DestCoords[2].x = RightRect;
- DestCoords[2].y = DestCoords[3].y = BottomRect;
- // Use IntGdiPolyPolygon so to support PATH.
- return IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1);
- }
// Rectangle Path only.
if ( PATH_IsPathOpen(dc->dclevel) )
{
DestRect.bottom--;
}
+ DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(dc);
ret = FALSE;
goto cleanup;
}
+
psurf = dc->dclevel.pSurface;
if (!psurf)
{
}
cleanup:
+ DC_vFinishBlit(dc, NULL);
+
/* Move current position in DC?
MSDN: The current position is neither used nor updated by Rectangle. */
return TRUE;
}
- ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
- DC_UnlockDc ( dc );
+ /* Do we rotate or shear? */
+ if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE))
+ {
+ POINTL DestCoords[4];
+ ULONG PolyCounts = 4;
+
+ DestCoords[0].x = DestCoords[3].x = LeftRect;
+ DestCoords[0].y = DestCoords[1].y = TopRect;
+ DestCoords[1].x = DestCoords[2].x = RightRect;
+ DestCoords[2].y = DestCoords[3].y = BottomRect;
+ // Use IntGdiPolyPolygon so to support PATH.
+ ret = IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1);
+ }
+ else
+ {
+ ret = IntRectangle(dc, LeftRect, TopRect, RightRect, BottomRect );
+ }
+
+ DC_UnlockDc(dc);
return ret;
}
}
if (!PenWidth) PenWidth = 1;
- pbrushLine->ptPenWidth.x = PenWidth;
+ pbrushLine->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.top = Top;
RectBounds.bottom += dc->ptlDCOrig.y;
pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
- if (NULL == pbrushFill)
+ if (NULL == pbrushFill)
{
DPRINT1("FillRound Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
ret = FALSE;
- }
+ }
else
{
RtlCopyMemory(&brushTemp, pbrushFill, sizeof(brushTemp));
{
PDC pdc;
SURFACE *psurf;
- PPALETTE ppal;
EXLATEOBJ exlo;
RECTL rclExtent;
POINTL ptlDitherOrg;
ULONG i;
BOOL bRet;
- HPALETTE hDestPalette;
- /* Check parameters */
- if (ulMode == GRADIENT_FILL_TRIANGLE)
+ /* check parameters */
+ if (ulMode & GRADIENT_FILL_TRIANGLE)
{
PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh;
/* Lock the output DC */
pdc = DC_LockDc(hdc);
- if (!pdc)
+ if(!pdc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- if (pdc->dctype == DC_TYPE_INFO)
+ if(pdc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(pdc);
/* Yes, Windows really returns TRUE in this case */
}
psurf = pdc->dclevel.pSurface;
- if (!psurf)
+ if(!psurf)
{
/* Memory DC with no surface selected */
DC_UnlockDc(pdc);
- return TRUE; // CHECKME
+ return TRUE; //CHECKME
}
/* calculate extent */
rclExtent.top = min(rclExtent.top, (pVertex + i)->y);
rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y);
}
-
IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2);
+
rclExtent.left += pdc->ptlDCOrig.x;
rclExtent.right += pdc->ptlDCOrig.x;
rclExtent.top += pdc->ptlDCOrig.y;
ptlDitherOrg.x = ptlDitherOrg.y = 0;
IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);
+
ptlDitherOrg.x += pdc->ptlDCOrig.x;
ptlDitherOrg.y += pdc->ptlDCOrig.y;
- hDestPalette = psurf->hDIBPalette;
- if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
-
- ppal = PALETTE_LockPalette(hDestPalette);
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
ASSERT(pdc->rosdc.CombinedClip);
+ DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);
+
bRet = IntEngGradientFill(&psurf->SurfObj,
- pdc->rosdc.CombinedClip,
- &exlo.xlo,
- pVertex,
- nVertex,
- pMesh,
- nMesh,
- &rclExtent,
- &ptlDitherOrg,
- ulMode);
+ pdc->rosdc.CombinedClip,
+ &exlo.xlo,
+ pVertex,
+ nVertex,
+ pMesh,
+ nMesh,
+ &rclExtent,
+ &ptlDitherOrg,
+ ulMode);
EXLATEOBJ_vCleanup(&exlo);
-
- if (ppal)
- PALETTE_UnlockPalette(ppal);
-
+ DC_vFinishBlit(pdc, NULL);
DC_UnlockDc(pdc);
return bRet;
return FALSE;
}
- cbVertex = nVertex * sizeof(TRIVERTEX);
- if (cbVertex + cbMesh <= cbVertex)
+ cbVertex = nVertex * sizeof(TRIVERTEX) ;
+ if(cbVertex + cbMesh <= cbVertex)
{
/* Overflow */
- return FALSE;
+ return FALSE ;
}
/* Allocate a kernel mode buffer */
SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE);
- if (!SafeVertex)
+ if(!SafeVertex)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
PDC dc;
PDC_ATTR pdcattr;
SURFACE *psurf = NULL;
- HPALETTE hpal;
- PPALETTE ppal;
EXLATEOBJ exlo;
BOOL Ret = FALSE;
RECTL DestRect;
goto cleanup;
}
- hpal = dc->dclevel.pSurface->hDIBPalette;
- if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
- ppal = PALETTE_ShareLockPalette(hpal);
-
- EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0xffffff, 0);
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);
/* Only solid fills supported for now
* How to support pattern brushes and non standard surfaces (not offering dib functions):
Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
EXLATEOBJ_vCleanup(&exlo);
- PALETTE_ShareUnlockPalette(ppal);
cleanup:
DC_UnlockDc(dc);
Size->cx = (TotalWidth + 32) >> 6;
Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight);
- Size->cy = EngMulDiv(Size->cy, IntGdiGetDeviceCaps(dc, LOGPIXELSY), 72);
+ Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72);
return TRUE;
}
LONGLONG TextLeft, RealXStart;
ULONG TextTop, previous, BackgroundLeft;
FT_Bool use_kerning;
- RECTL DestRect, MaskRect;
+ RECTL DestRect, MaskRect, DummyRect = {0, 0, 0, 0};
POINTL SourcePoint, BrushOrigin;
HBITMAP HSourceGlyph;
SURFOBJ *SourceGlyphSurf;
BOOLEAN Render;
POINT Start;
BOOL DoBreak = FALSE;
- HPALETTE hDestPalette;
- PPALETTE ppalDst;
USHORT DxShift;
// TODO: Write test-cases to exactly match real Windows in different
pdcattr = dc->pdcattr;
- if (pdcattr->ulDirty_ & DIRTY_TEXT)
- DC_vUpdateTextBrush(dc);
-
if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE)
{
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
IntLPtoDP(dc, (POINT *)lprc, 2);
}
- psurf = dc->dclevel.pSurface;
- if (!psurf)
- {
- goto fail;
- }
- SurfObj = &psurf->SurfObj;
-
Start.x = XStart;
Start.y = YStart;
IntLPtoDP(dc, &Start, 1);
DestRect.right += dc->ptlDCOrig.x;
DestRect.bottom += dc->ptlDCOrig.y;
+ DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+
+ if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
+ DC_vUpdateBackgroundBrush(dc);
+
IntEngBitBlt(
- &psurf->SurfObj,
+ &dc->dclevel.pSurface->SurfObj,
NULL,
NULL,
dc->rosdc.CombinedClip,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
fuOptions &= ~ETO_OPAQUE;
+ DC_vFinishBlit(dc, NULL);
}
else
{
TextTop = YStart;
BackgroundLeft = (RealXStart + 32) >> 6;
- /* Create the xlateobj */
- hDestPalette = psurf->hDIBPalette;
- if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
- ppalDst = PALETTE_LockPalette(hDestPalette);
- EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0);
- EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0);
- PALETTE_UnlockPalette(ppalDst);
+ /* Lock blit with a dummy rect */
+ DC_vPrepareDCsForBlit(dc, DummyRect, NULL, DummyRect);
+ psurf = dc->dclevel.pSurface ;
+ SurfObj = &psurf->SurfObj ;
+
+ EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
+
+ if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND))
+ DC_vUpdateBackgroundBrush(dc) ;
+
+ if(dc->pdcattr->ulDirty_ & DIRTY_TEXT)
+ DC_vUpdateTextBrush(dc) ;
/*
* The main rendering loop.
*/
-
for (i = 0; i < Count; i++)
{
if (fuOptions & ETO_GLYPH_INDEX)
DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6;
DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6);
DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6);
+ MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
IntEngBitBlt(
&psurf->SurfObj,
NULL,
&dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
+ MouseSafetyOnDrawEnd(dc->ppdev);
BackgroundLeft = DestRect.right;
+
}
DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left;
DestRect.right = lprc->right + dc->ptlDCOrig.x;
DoBreak = TRUE;
}
-
+ MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
IntEngMaskBlt(
SurfObj,
SourceGlyphSurf,
(PPOINTL)&MaskRect,
&dc->eboText.BrushObject,
&BrushOrigin);
+ MouseSafetyOnDrawEnd(dc->ppdev) ;
EngUnlockSurface(SourceGlyphSurf);
EngDeleteSurface((HSURF)HSourceGlyph);
String++;
}
-
IntUnLockFreeType;
+ DC_vFinishBlit(dc, NULL) ;
EXLATEOBJ_vCleanup(&exloRGB2Dst);
EXLATEOBJ_vCleanup(&exloDst2RGB);
if (TextObj != NULL)
fail:
if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj);
+
DC_UnlockDc(dc);
return FALSE;
Flags = DSS_TIMER_EVENT;
Device = IntEnumHDev();
-
- SurfObj = EngLockSurface( Device->pSurface );
+// UNIMPLEMENTED;
+//ASSERT(FALSE);
+ SurfObj = 0;// EngLockSurface( Device->pSurface );
if(!SurfObj) return;
DoDeviceSync( SurfObj, NULL, Flags);
EngUnlockSurface(SurfObj);
/** INCLUDES ******************************************************************/
-//#define GDI_DEBUG
+#define GDI_DEBUG
#include <win32k.h>
#define NDEBUG
PEPROCESS OldProcess;
Object->BaseFlags |= BASEFLAG_READY_TO_DIE;
DPRINT("Object %p, ulShareCount = %d\n", Object->hHmgr, Object->ulShareCount);
- //GDIDBG_TRACECALLER();
- //GDIDBG_TRACESHARELOCKER(GDI_HANDLE_GET_INDEX(hObj));
- /* Set NULL owner. This will permit an other process to kill the object
- * Do the work here to avoid race conditions */
+ /* Set NULL owner. Do the work here to avoid race conditions */
Status = PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)PrevProcId & ~0x1), &OldProcess);
if (NT_SUCCESS(Status))
{
}
ObDereferenceObject(OldProcess);
}
- (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
+ (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, NULL);
/* Don't wait on shared locks */
return FALSE;
}
*/
DPRINT1("Object->cExclusiveLock = %d\n", Object->cExclusiveLock);
GDIDBG_TRACECALLER();
- GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj));
+ GDIDBG_TRACELOCKER(hObj);
(void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
/* do not assert here for it will call again from dxg.sys it being call twice */
}
DPRINT1("Type = 0x%lx, KernelData = 0x%p, ProcessId = 0x%p\n", Entry->Type, Entry->KernelData, Entry->ProcessId);
GDIDBG_TRACECALLER();
- GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj));
+ GDIDBG_TRACEALLOCATOR(hObj);
}
}
break;
case GDI_OBJECT_TYPE_DC:
- DC_FreeDcAttr(hObject);
+// DC_FreeDcAttr(hObject);
break;
}
if(hObj == NULL)
return NULL ;
+ GDIDBG_INITLOOPTRACE();
+
HandleIndex = GDI_HANDLE_GET_INDEX(hObj);
HandleType = GDI_HANDLE_GET_TYPE(hObj);
HandleUpper = GDI_HANDLE_GET_UPPER(hObj);
/* Check that the handle index is valid. */
- if (HandleIndex >= GDI_HANDLE_COUNT)
+ if (HandleIndex >= GDI_HANDLE_COUNT )
return NULL;
Entry = &GdiHandleTable->Entries[HandleIndex];
{
DPRINT1("Tried to lock object (0x%p) of wrong owner! ProcessId = %p, HandleProcessId = %p\n", hObj, ProcessId, HandleProcessId);
GDIDBG_TRACECALLER();
- GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj));
+ GDIDBG_TRACEALLOCATOR(hObj);
return NULL;
}
/*
* The handle is currently locked, wait some time and try again.
*/
+ GDIDBG_TRACELOOP(hObj, PrevProcId, NULL);
DelayExecution();
continue;
return MappedView;
}
+/* Locks 2 or 3 objects at a time */
+VOID
+INTERNAL_CALL
+GDIOBJ_LockMultipleObjs(ULONG ulCount,
+ IN HGDIOBJ* ahObj,
+ OUT PGDIOBJ* apObj)
+{
+ UINT auiIndices[3] = {0,1,2};
+ UINT i, tmp ;
+ BOOL bUnsorted = TRUE;
+
+ /* First is greatest */
+ while(bUnsorted)
+ {
+ bUnsorted = FALSE;
+ for(i=1; i<ulCount; i++)
+ {
+ if((ULONG_PTR)ahObj[auiIndices[i-1]] < (ULONG_PTR)ahObj[auiIndices[i]])
+ {
+ tmp = auiIndices[i-1];
+ auiIndices[i-1] = auiIndices[i];
+ auiIndices[i] = tmp;
+ bUnsorted = TRUE;
+ }
+ }
+ }
+
+ for(i=0;i<ulCount;i++)
+ apObj[auiIndices[i]] = GDIOBJ_LockObj(ahObj[auiIndices[i]], GDI_OBJECT_TYPE_DONTCARE);
+}
+
+
/** PUBLIC FUNCTIONS **********************************************************/
BOOL
{
pDC = DC_LockDc ( hDC );
MmCopyFromCaller(&pDC->dcattr, pDC->pdcattr, sizeof(DC_ATTR));
+ DC_vFreeDcAttr(pDC);
DC_UnlockDc( pDC );
- DC_FreeDcAttr( hDC ); // Free the dcattr!
-
if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible!
return Ret;
}
palPtr = (PALOBJ*) palGDI;
if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE)
- palGDI->Mode |= PAL_GAMMACORRECTION;
+ palGDI->flFlags |= PAL_GAMMACORRECTION;
else
- palGDI->Mode &= ~PAL_GAMMACORRECTION;
+ palGDI->flFlags &= ~PAL_GAMMACORRECTION;
if (!(pGDev->flFlags & PDEV_DRIVER_PUNTED_CALL)) // No punting, we hook
{
}
else
{
- if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
- DC_vUpdateLineBrush(dc);
-
psurf = dc->dclevel.pSurface;
if (NULL == psurf)
{
if (PATH_IsPathOpen(dc->dclevel))
return PATH_Polyline(dc, pt, Count);
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(dc);
}
}
+ DC_vFinishBlit(dc, NULL);
+
return Ret;
}
{
DC *dc;
BOOL Ret;
+ RECT rcLockRect ;
dc = DC_LockDc(hDC);
if (!dc)
return TRUE;
}
+ rcLockRect.left = dc->pdcattr->ptlCurrent.x;
+ rcLockRect.top = dc->pdcattr->ptlCurrent.y;
+ rcLockRect.right = XEnd;
+ rcLockRect.bottom = YEnd;
+
+ IntLPtoDP(dc, &rcLockRect, 2);
+
+ /* The DCOrg is in device coordinates */
+ rcLockRect.left += dc->ptlDCOrig.x;
+ rcLockRect.top += dc->ptlDCOrig.y;
+ rcLockRect.right += dc->ptlDCOrig.x;
+ rcLockRect.bottom += dc->ptlDCOrig.y;
+
+ DC_vPrepareDCsForBlit(dc, rcLockRect, NULL, rcLockRect);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
Ret = IntGdiLineTo(dc, XEnd, YEnd);
+ DC_vFinishBlit(dc, NULL);
+
DC_UnlockDc(dc);
return Ret;
}
static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the pallete and restore it */
-PALETTE gpalRGB, gpalBGR, gpalMono;
+PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault;
+PPALETTE appalSurfaceDefault[11];
const PALETTEENTRY g_sysPalTemplate[NB_RESERVED_COLORS] =
{
/* palette_size = visual->map_entries; */
- gpalRGB.Mode = PAL_RGB;
+ gpalRGB.flFlags = PAL_RGB;
gpalRGB.RedMask = RGB(0xFF, 0x00, 0x00);
gpalRGB.GreenMask = RGB(0x00, 0xFF, 0x00);
gpalRGB.BlueMask = RGB(0x00, 0x00, 0xFF);
+ gpalRGB.BaseObject.ulShareCount = 0;
+ gpalRGB.BaseObject.BaseFlags = 0 ;
- gpalBGR.Mode = PAL_BGR;
+ gpalBGR.flFlags = PAL_BGR;
gpalBGR.RedMask = RGB(0x00, 0x00, 0xFF);
gpalBGR.GreenMask = RGB(0x00, 0xFF, 0x00);
gpalBGR.BlueMask = RGB(0xFF, 0x00, 0x00);
+ gpalBGR.BaseObject.ulShareCount = 0;
+ gpalBGR.BaseObject.BaseFlags = 0 ;
+
+ gpalRGB555.flFlags = PAL_RGB16_555 | PAL_BITFIELDS;
+ gpalRGB555.RedMask = 0x7C00;
+ gpalRGB555.GreenMask = 0x3E0;
+ gpalRGB555.BlueMask = 0x1F;
+ gpalRGB555.BaseObject.ulShareCount = 0;
+ gpalRGB555.BaseObject.BaseFlags = 0 ;
+
+ gpalRGB565.flFlags = PAL_RGB16_565 | PAL_BITFIELDS;
+ gpalRGB565.RedMask = 0xF800;
+ gpalRGB565.GreenMask = 0x7E0;
+ gpalRGB565.BlueMask = 0x1F;
+ gpalRGB565.BaseObject.ulShareCount = 0;
+ gpalRGB565.BaseObject.BaseFlags = 0 ;
memset(&gpalMono, 0, sizeof(PALETTE));
- gpalMono.Mode = PAL_MONOCHROME;
+ gpalMono.flFlags = PAL_MONOCHROME;
+ gpalMono.BaseObject.ulShareCount = 0;
+ gpalMono.BaseObject.BaseFlags = 0 ;
+
+ /* Initialize default surface palettes */
+ gppalDefault = PALETTE_ShareLockPalette(hpalette);
+ appalSurfaceDefault[BMF_1BPP] = &gpalMono;
+ appalSurfaceDefault[BMF_4BPP] = gppalDefault;
+ appalSurfaceDefault[BMF_8BPP] = gppalDefault;
+ appalSurfaceDefault[BMF_16BPP] = &gpalRGB565;
+ appalSurfaceDefault[BMF_24BPP] = &gpalBGR;
+ appalSurfaceDefault[BMF_32BPP] = &gpalBGR;
+ appalSurfaceDefault[BMF_4RLE] = gppalDefault;
+ appalSurfaceDefault[BMF_8RLE] = gppalDefault;
+ appalSurfaceDefault[BMF_JPEG] = &gpalRGB;
+ appalSurfaceDefault[BMF_PNG] = &gpalRGB;
return hpalette;
}
NewPalette = PalGDI->BaseObject.hHmgr;
PalGDI->Self = NewPalette;
- PalGDI->Mode = Mode;
+ PalGDI->flFlags = Mode;
if (NULL != Colors)
{
RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(PALETTEENTRY) * NumColors);
}
- if (PAL_INDEXED == Mode)
+ if (Mode & PAL_INDEXED)
{
PalGDI->NumColors = NumColors;
}
- else if (PAL_BITFIELDS == Mode)
+ else if (Mode & PAL_BITFIELDS)
{
PalGDI->RedMask = Red;
PalGDI->GreenMask = Green;
PalGDI->BlueMask = Blue;
-
+
if (Red == 0x7c00 && Green == 0x3E0 && Blue == 0x1F)
- PalGDI->Mode |= PAL_RGB16_555;
+ PalGDI->flFlags |= PAL_RGB16_555;
else if (Red == 0xF800 && Green == 0x7E0 && Blue == 0x1F)
- PalGDI->Mode |= PAL_RGB16_565;
+ PalGDI->flFlags |= PAL_RGB16_565;
+ else if (Red == 0xFF0000 && Green == 0xFF00 && Blue == 0xFF)
+ PalGDI->flFlags |= PAL_BGR;
}
PALETTE_UnlockPalette(PalGDI);
NewPalette = PalGDI->BaseObject.hHmgr;
PalGDI->Self = NewPalette;
- PalGDI->Mode = PAL_INDEXED;
+ PalGDI->flFlags = PAL_INDEXED;
PalGDI->IndexedColors = ExAllocatePoolWithTag(PagedPool,
sizeof(PALETTEENTRY) * NumColors,
NTAPI
PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG ulColor)
{
- if (ppal->Mode & PAL_INDEXED) // use fl & PALINDEXED
+ if (ppal->flFlags & PAL_INDEXED) // use fl & PALINDEXED
return PALETTE_ulGetNearestPaletteIndex(ppal, ulColor);
else
return PALETTE_ulGetNearestBitFieldsIndex(ppal, ulColor);
{
ASSERT(pulColors);
- if (ppal->Mode & PAL_INDEXED || ppal->Mode & PAL_RGB)
+ if (ppal->flFlags & PAL_INDEXED || ppal->flFlags & PAL_RGB)
{
pulColors[0] = RGB(0xFF, 0x00, 0x00);
pulColors[1] = RGB(0x00, 0xFF, 0x00);
pulColors[2] = RGB(0x00, 0x00, 0xFF);
}
- else if (ppal->Mode & PAL_BGR)
+ else if (ppal->flFlags & PAL_BGR)
{
pulColors[0] = RGB(0x00, 0x00, 0xFF);
pulColors[1] = RGB(0x00, 0xFF, 0x00);
pulColors[2] = RGB(0xFF, 0x00, 0x00);
}
- else if (ppal->Mode & PAL_BITFIELDS)
+ else if (ppal->flFlags & PAL_BITFIELDS)
{
pulColors[0] = ppal->RedMask;
pulColors[1] = ppal->GreenMask;
{
HPALETTE Palette;
- Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue);
+ Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue);
if (Palette != NULL)
{
GDIOBJ_SetOwnership(Palette, NULL);
/* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */
RtlCopyMemory(PaletteEntry, PalGDI->IndexedColors + Start, sizeof(ULONG) * Colors);
- if (PalGDI->Mode & PAL_GAMMACORRECTION)
+ if (PalGDI->flFlags & PAL_GAMMACORRECTION)
ColorCorrection(PalGDI, (PPALETTEENTRY)PaletteEntry, Colors);
return Colors;
return nearest;
}
- if (palGDI->Mode & PAL_INDEXED)
+ if (palGDI->flFlags & PAL_INDEXED)
{
ULONG index;
index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color);
nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index);
}
- else if (palGDI->Mode & PAL_RGB || palGDI->Mode & PAL_BGR)
+ else if (palGDI->flFlags & PAL_RGB || palGDI->flFlags & PAL_BGR)
{
nearest = Color;
}
- else if (palGDI->Mode & PAL_BITFIELDS)
+ else if (palGDI->flFlags & PAL_BITFIELDS)
{
RBits = 8 - GetNumberOfBits(palGDI->RedMask);
GBits = 8 - GetNumberOfBits(palGDI->GreenMask);
if (ppal)
{
- if (ppal->Mode & PAL_INDEXED)
+ if (ppal->flFlags & PAL_INDEXED)
{
/* Return closest match for the given RGB color */
index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor);
FLOAT_POINT ellCorners[2];
pPath = PATH_LockPath( dc->dclevel.hPath );
- if (!pPath) return FALSE;
+ if (!pPath) return FALSE;
/* Check that path is open */
if(pPath->state!=PATH_Open)
if ( pPath->state != PATH_Open )
{
Ret = FALSE;
- goto ArcExit;
+ goto ArcExit;
}
/* Check for zero height / width */
pPath = PATH_LockPath( dc->dclevel.hPath );
if (!pPath) return FALSE;
-
+
/* Check that path is open */
if ( pPath->state != PATH_Open )
{
pPath = PATH_LockPath( dc->dclevel.hPath );
if (!pPath) return FALSE;
-
+
/* Check that path is open */
if ( pPath->state != PATH_Open )
{
numStrokes++;
j = 0;
if (numStrokes == 1)
- pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
+ pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH);
else
{
pOldStrokes = pStrokes; // Save old pointer.
}
}
- pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
+ pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
PATH_InitGdiPath(pNewPath);
pNewPath->state = PATH_Open;
}
IntGdiCloseFigure( pPath );
- PATH_UnlockPath( pPath );
+ PATH_UnlockPath( pPath );
return TRUE;
}
* PATH_ExtTextOut
*/
BOOL
-FASTCALL
+FASTCALL
PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc,
LPCWSTR str, UINT count, const INT *dx)
{
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
- }
+ }
pPath = PATH_LockPath( pDc->dclevel.hPath );
if (!pPath)
{
PPATH pPath;
PDC_ATTR pdcattr;
PDC dc = DC_LockDc ( hDC );
-
+
if ( !dc )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
pdcattr = dc->pdcattr;
if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
}
PATH_UnlockPath( pPath );
+ DC_vFinishBlit(dc, NULL);
DC_UnlockDc ( dc );
return ret;
}
pDc = DC_LockDc(hDC);
if (!pDc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
return FALSE;
}
+ DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
+ NULL, pDc->rosdc.CombinedClip->rclBounds);
+
pdcattr = pDc->pdcattr;
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
if (bRet) PATH_EmptyPath(pPath);
PATH_UnlockPath( pPath );
+ DC_vFinishBlit(pDc, NULL);
DC_UnlockDc(pDc);
return bRet;
}
return FALSE;
}
+ DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds,
+ NULL, pDc->rosdc.CombinedClip->rclBounds);
+
pdcattr = pDc->pdcattr;
if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
DC_vUpdateLineBrush(pDc);
bRet = PATH_StrokePath(pDc, pPath);
+
+ DC_vFinishBlit(pDc, NULL);
PATH_EmptyPath(pPath);
PATH_UnlockPath( pPath );
NtGdiWidenPath(HDC hDC)
{
BOOL Ret;
- PDC pdc = DC_LockDc ( hDC );
+ PDC pdc = DC_LockDc ( hDC );
if ( !pdc )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
{
HPEN hPen;
PBRUSH pbrushPen;
- static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55};
- static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0};
- static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38};
- static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0};
- static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38};
+ static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55, 0};
+ static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0, 0};
+ static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38, 0};
+ static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0, 0};
+ static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38, 0};
dwWidth = abs(dwWidth);
case PS_ALTERNATE:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
break;
case PS_DOT:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
break;
case PS_DASH:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
break;
case PS_DASHDOT:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
break;
case PS_DASHDOTDOT:
pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP;
- pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
+ pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
break;
case PS_INSIDEFRAME:
else if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr;
break;
case SYSRGN:
- if (pDC->prgnVis) hSrc = ((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr;
+ if (pDC->prgnVis) hSrc = pDC->prgnVis->BaseObject.hHmgr;
break;
default:
hSrc = 0;
StockObjects[NULL_PEN] = IntCreateStockPen(NullPen.lopnStyle, NullPen.lopnWidth.x, BS_SOLID, NullPen.lopnColor);
StockObjects[20] = NULL; /* TODO: Unknown internal stock object */
- StockObjects[DEFAULT_BITMAP] = IntGdiCreateBitmap(1, 1, 1, 1, NULL);
+ StockObjects[DEFAULT_BITMAP] = GreCreateBitmap(1, 1, 1, 1, NULL);
(void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&SystemFixedFont, (HFONT*)&StockObjects[SYSTEM_FIXED_FONT]);
(void) TextIntCreateFontIndirect(&DefaultGuiFont, (HFONT*)&StockObjects[DEFAULT_GUI_FONT]);
- StockObjects[DEFAULT_PALETTE] = (HGDIOBJ)PALETTE_Init();
+ StockObjects[DEFAULT_PALETTE] = (HGDIOBJ)gppalDefault->BaseObject.hHmgr;
for (Object = 0; Object < NB_STOCK_OBJECTS; Object++)
{
return NULL;
}
-/*
- * @unimplemented
- */
-LPWSTR
-APIENTRY
-EngGetDriverName ( IN HDEV hdev )
-{
- // www.osr.com/ddk/graphics/gdifncs_2gx3.htm
- UNIMPLEMENTED;
- return NULL;
-}
-
/*
* @unimplemented
*/
<file>dib.c</file>
<file>floodfill.c</file>
<file>stretchblt.c</file>
+ <file>alphablend.c</file>
<if property="ARCH" value="i386">
<directory name="i386">
</directory>
</if>
<file>gradient.c</file>
+ <file>ldevobj.c</file>
<file>lineto.c</file>
<file>mapping.c</file>
<file>mem.c</file>
<file>engmisc.c</file>
<file>mouse.c</file>
<file>paint.c</file>
+ <file>pdevobj.c</file>
<file>perfcnt.c</file>
+ <file>rlecomp.c</file>
<file>semaphor.c</file>
<file>sort.c</file>
<file>string.c</file>
<file>engwindow.c</file>
<file>xlate.c</file>
</directory>
- <directory name="ldr">
- <file>loader.c</file>
- </directory>
<directory name="main">
<file>dllmain.c</file>
</directory>