[YAROTOWS] Reintegrate the branch. For a brighter future.

Main features:
- Implement LDEVOBJ api. Responsible for loading dlls (display drivers, font drivers, keyboard layout, etc), replacing code in different locations.
- Implement PDEVOBJ api. A PDEVOBJ represents a physical device and is the core component for handling multiple display devices.
- Rewrite device locking. The new method was neccessary to allow dynamic mode switching.
- Implement support for enumerating display devices and settings.
- Implement dynamic mode switching.
- Implement a number of Eng mapping functions.
- Rewrite Eng level surface handling for cleaner code and better compatability.
- Rewrite parts of the DIB handling code.
- Rewrite DC creation and deletion. Deletion and cleanup is now completely callback based. Now we don't leak the DC objects when terminating a process, like we did before.
- Improve the XLATE and BRUSH code, removing several old hacks.
- Improve icon code.

Thanks to Jerome Gardou, Kamil Hornicek and everyone helping.

svn path=/trunk/; revision=49275
This commit is contained in:
Timo Kreuzer
2010-10-25 17:36:27 +00:00
103 changed files with 7375 additions and 7436 deletions

View File

@@ -435,6 +435,12 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
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);

View File

@@ -1085,7 +1085,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Type",0x00010001,0x00000001
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

View File

@@ -586,6 +586,8 @@ media\fonts\symbol.ttf 3
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

View File

@@ -146,7 +146,7 @@ typedef BOOL (WINAPI *STARTPAGEPRINTER) (HANDLE);
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);
@@ -173,10 +173,10 @@ HEAP_strdupA2W(
VOID
HEAP_free(LPVOID memory);
VOID
VOID
FASTCALL
FONT_TextMetricWToA(
const TEXTMETRICW *ptmW,
const TEXTMETRICW *ptmW,
LPTEXTMETRICA ptmA
);
@@ -279,7 +279,7 @@ WINAPI
GdiSetLastError( DWORD dwErrCode );
DWORD WINAPI GdiGetCodePage(HDC);
UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO );
UINT FASTCALL DIB_BitmapBitsSize( CONST BITMAPINFO* );
int
WINAPI

View File

@@ -166,6 +166,10 @@ SetPixelFormat(HDC hdc,
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);

View File

@@ -34,7 +34,7 @@ DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
UINT
FASTCALL
DIB_BitmapBitsSize( PBITMAPINFO Info )
DIB_BitmapBitsSize( CONST BITMAPINFO* Info )
{
UINT Ret;
@@ -43,16 +43,16 @@ DIB_BitmapBitsSize( PBITMAPINFO Info )
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;
@@ -132,12 +132,12 @@ WINAPI
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
@@ -148,13 +148,13 @@ GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
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;
}
}
@@ -189,7 +189,7 @@ CreateDIBSection(
{ // 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);
@@ -319,7 +319,7 @@ CreateBitmapIndirect(const BITMAP *pbm)
(!(pbm->bmWidthBytes & 1)) )
{
bitmap = CreateBitmap(pbm->bmWidth,
pbm->bmHeight,
pbm->bmPlanes,
@@ -409,7 +409,7 @@ GetDIBits(
{
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);
@@ -461,78 +461,61 @@ CreateDIBitmap( HDC hDC,
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;
}
@@ -588,7 +571,7 @@ SetDIBits(HDC hDC,
if ( hOldBitmap )
{
if ( hDC )
if ( hDC )
hPal = SelectPalette(SavehDC, (HPALETTE)GetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE), FALSE);
if ( lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
@@ -782,7 +765,7 @@ SetDIBitsToDevice(
/*
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,
@@ -806,7 +789,7 @@ SetDIBitsToDevice(
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
if (lpbmi != pConvertedInfo)
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
return LinesCopied;
}
@@ -886,17 +869,12 @@ StretchDIBits(HDC hdc,
}
}
#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);
@@ -933,7 +911,7 @@ StretchDIBits(HDC hdc,
/*
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,

View File

@@ -15,7 +15,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver,
{
UNICODE_STRING Device, Output;
HDC hDC = NULL;
BOOL Display = FALSE, Default = TRUE;
BOOL Display = FALSE, Default = FALSE;
ULONG UMdhpdev = 0;
HANDLE hspool = NULL;
@@ -31,7 +31,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver,
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
@@ -60,7 +60,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver,
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.
@@ -318,7 +318,7 @@ WINAPI
DeleteObject(HGDIOBJ hObject)
{
UINT Type = 0;
/* From Wine: DeleteObject does not SetLastError() on a null object */
if(!hObject) return FALSE;
@@ -332,7 +332,7 @@ DeleteObject(HGDIOBJ hObject)
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;
@@ -348,7 +348,7 @@ DeleteObject(HGDIOBJ hObject)
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 );
@@ -533,7 +533,7 @@ GetDeviceCaps(HDC hDC,
return NtGdiGetDeviceCaps(hDC,i);
}
DPRINT("Device CAPS2\n");
switch (i)
{
case DRIVERVERSION:
@@ -1603,7 +1603,7 @@ SelectObject(HDC hDC,
#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;

View File

@@ -1,2 +1,12 @@
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);

View File

@@ -457,7 +457,6 @@ ChangeDisplaySettingsExA(
LONG rc;
UNICODE_STRING DeviceName;
PUNICODE_STRING pDeviceName = &DeviceName;
LPDEVMODEW pDevModeW;
if (lpszDeviceName != NULL)
{
@@ -471,14 +470,19 @@ ChangeDisplaySettingsExA(
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 );
@@ -539,6 +543,6 @@ ChangeDisplaySettingsW(
DWORD dwflags)
{
if(lpDevMode)
lpDevMode->dmDriverExtra = 0;
lpDevMode->dmDriverExtra = 0;
return ChangeDisplaySettingsExW ( NULL, lpDevMode, NULL, dwflags, 0 );
}

View File

@@ -298,7 +298,7 @@ IntGetWndProc(PWND pWnd, BOOL Ansi)
}
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
@@ -831,7 +831,6 @@ CreateSmallIcon(HICON StdIcon)
int SmallIconWidth;
int SmallIconHeight;
BITMAP StdBitmapInfo;
HDC hInfoDc = NULL;
HDC hSourceDc = NULL;
HDC hDestDc = NULL;
ICONINFO SmallInfo;
@@ -867,15 +866,6 @@ CreateSmallIcon(HICON StdIcon)
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)
{
@@ -895,7 +885,7 @@ CreateSmallIcon(HICON StdIcon)
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)
{
@@ -921,8 +911,7 @@ CreateSmallIcon(HICON StdIcon)
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");
@@ -976,10 +965,6 @@ cleanup:
{
DeleteDC(hSourceDc);
}
if (NULL != hInfoDc)
{
DeleteDC(hInfoDc);
}
return SmallIcon;
}
@@ -1070,9 +1055,9 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx,
clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
clsMenuName.pusMenuName = &MenuName;
Atom = NtUserRegisterClassExWOW( &WndClass,
&ClassName,
&ClassName,
NULL, //PUNICODE_STRING ClsNVersion,
&clsMenuName,
fnID,

View File

@@ -458,10 +458,16 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
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;
@@ -485,8 +491,8 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
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;
@@ -523,7 +529,7 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
ret = TRUE;
done:
DeleteDC( hdc );
if(hdc) DeleteDC( hdc );
HeapFree( GetProcessHeap(), 0, info );
return ret;
}

View File

@@ -1373,9 +1373,9 @@ IntDrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
}
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))
@@ -1388,13 +1388,11 @@ IntDrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
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;
}
@@ -1418,8 +1416,6 @@ cleanup:
SelectObject(hdc, hbsave);
if(hbmsave)
SelectObject(memdc, hbmsave);
if(hbrtmp)
DeleteObject(hbrtmp);
if(hbm)
DeleteObject(hbm);
if(memdc)

View File

@@ -68,6 +68,10 @@ DtbgWindowProc(HWND Wnd,
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;

View File

@@ -9,9 +9,10 @@
<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>

View File

@@ -0,0 +1,123 @@
/*
* 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;
}

View File

@@ -29,25 +29,25 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] =
{
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 */
{

View File

@@ -78,7 +78,6 @@ BOOLEAN DIB_1BPP_BitBlt(PBLTINFO);
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);
@@ -88,7 +87,6 @@ BOOLEAN DIB_4BPP_BitBlt(PBLTINFO);
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);
@@ -98,7 +96,6 @@ BOOLEAN DIB_8BPP_BitBlt(PBLTINFO);
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);
@@ -108,7 +105,6 @@ BOOLEAN DIB_16BPP_BitBlt(PBLTINFO);
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);
@@ -132,6 +128,7 @@ BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATE
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];

View File

@@ -525,174 +525,4 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
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 */

View File

@@ -33,7 +33,7 @@ DIB_1BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
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++;
@@ -43,7 +43,7 @@ DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
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++;
@@ -474,13 +474,4 @@ DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
return FALSE;
}
BOOLEAN
DIB_1BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
RECTL* SourceRect, CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
{
UNIMPLEMENTED;
return FALSE;
}
/* EOF */

View File

@@ -37,7 +37,7 @@ DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
LONG lDelta = SurfObj->lDelta;
c &= 0xFFFFFF;
while(y1++ < y2)
while(y1++ < y2)
{
*(PUSHORT)(addr) = c & 0xFFFF;
*(addr + 2) = c >> 16;
@@ -466,7 +466,6 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
{
INT Rows, Cols, SrcX, SrcY;
register PUCHAR Dst;
ULONG DstDelta;
BLENDFUNCTION BlendFunc;
register NICEPIXEL32 DstPixel, SrcPixel;
UCHAR Alpha, SrcBpp;
@@ -475,9 +474,6 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
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)
{
@@ -503,39 +499,41 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
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;
}

View File

@@ -54,8 +54,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
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)
@@ -83,8 +83,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
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++)
@@ -156,8 +156,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
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;
@@ -182,7 +182,7 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
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)
@@ -197,10 +197,10 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo)
}
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--)
@@ -348,7 +348,6 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
{
INT Rows, Cols, SrcX, SrcY;
register PULONG Dst;
ULONG DstDelta;
BLENDFUNCTION BlendFunc;
register NICEPIXEL32 DstPixel, SrcPixel;
UCHAR Alpha, SrcBpp;
@@ -357,9 +356,6 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
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)
{
@@ -385,35 +381,38 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
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;

View File

@@ -32,7 +32,7 @@ DIB_4BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
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)
@@ -48,7 +48,7 @@ DIB_4BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
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;
@@ -81,8 +81,8 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
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));
}
@@ -375,13 +375,4 @@ DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
return FALSE;
}
BOOLEAN
DIB_4BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
RECTL* SourceRect, CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
{
UNIMPLEMENTED;
return FALSE;
}
/* EOF */

View File

@@ -43,7 +43,7 @@ DIB_8BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
LONG lDelta = SurfObj->lDelta;
byteaddr = addr;
while(y1++ < y2)
while(y1++ < y2)
{
*addr = c;
@@ -74,8 +74,8 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo)
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));
}
@@ -362,130 +362,4 @@ DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
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 */

View File

@@ -1,4 +1,4 @@
/*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: GDI alpha blending functions
@@ -25,10 +25,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
IN PRECTL SourceRect,
IN BLENDOBJ *BlendObj)
{
RECTL SourceStretchedRect;
SIZEL SourceStretchedSize;
HBITMAP SourceStretchedBitmap = 0;
SURFOBJ* SourceStretchedObj = NULL;
RECTL InputRect;
RECTL OutputRect;
RECTL ClipRect;
@@ -39,7 +35,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
INTENG_ENTER_LEAVE EnterLeaveDest;
SURFOBJ* InputObj;
SURFOBJ* OutputObj;
LONG Width;
LONG ClippingType;
RECT_ENUM RectEnum;
BOOL EnumMore;
@@ -71,7 +66,7 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
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);
@@ -111,68 +106,9 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
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;
@@ -182,16 +118,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
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;
@@ -261,16 +187,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest,
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
if (SourceStretchedObj != NULL)
{
EngFreeMem(SourceStretchedObj->pvBits);
EngUnlockSurface(SourceStretchedObj);
}
if (SourceStretchedBitmap != 0)
{
EngDeleteSurface((HSURF)SourceStretchedBitmap);
}
return Ret;
}
@@ -305,17 +221,8 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest,
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,
@@ -328,12 +235,6 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest,
DestRect, SourceRect, BlendObj);
}
MouseSafetyOnDrawEnd(psoSource);
if (psoSource != psoDest)
SURFACE_UnlockBitmapBits(psurfSource);
MouseSafetyOnDrawEnd(psoDest);
SURFACE_UnlockBitmapBits(psurfDest);
return ret;
}

View File

@@ -522,7 +522,7 @@ EngBitBlt(SURFOBJ *DestObj,
}
BOOL APIENTRY
IntEngBitBltEx(
IntEngBitBlt(
SURFOBJ *psoTrg,
SURFOBJ *psoSrc,
SURFOBJ *psoMask,
@@ -533,8 +533,7 @@ IntEngBitBltEx(
POINTL *pptlMask,
BRUSHOBJ *pbo,
POINTL *pptlBrush,
ROP4 rop4,
BOOL bRemoveMouse)
ROP4 rop4)
{
SURFACE *psurfTrg;
SURFACE *psurfSrc = NULL;
@@ -583,28 +582,11 @@ IntEngBitBltEx(
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);
@@ -614,7 +596,7 @@ IntEngBitBltEx(
}
/* Is the source surface device managed? */
else if (psoSrc && psurfSrc->flHooks & HOOK_BITBLT)
else if (psoSrc && psurfSrc->flags & HOOK_BITBLT)
{
pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt;
}
@@ -637,21 +619,6 @@ IntEngBitBltEx(
// FIXME: cleanup temp surface!
if (bRemoveMouse)
{
MouseSafetyOnDrawEnd(psoTrg);
if (psoSrc)
{
MouseSafetyOnDrawEnd(psoSrc);
if (psoSrc != psoTrg)
{
SURFACE_UnlockBitmapBits(psurfSrc);
}
}
SURFACE_UnlockBitmapBits(psurfTrg);
}
return bResult;
}
@@ -983,27 +950,20 @@ IntEngMaskBlt(SURFOBJ *psoDest,
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;
}

View File

@@ -53,13 +53,7 @@ EngCopyBits(SURFOBJ *psoDest,
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
@@ -73,7 +67,7 @@ EngCopyBits(SURFOBJ *psoDest,
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);
@@ -86,7 +80,7 @@ EngCopyBits(SURFOBJ *psoDest,
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);
@@ -180,12 +174,6 @@ EngCopyBits(SURFOBJ *psoDest,
}
cleanup:
if (psoDest != psoSource)
{
SURFACE_UnlockBitmapBits(psurfDest);
}
SURFACE_UnlockBitmapBits(psurfSource);
return ret;
}
@@ -198,20 +186,7 @@ IntEngCopyBits(
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);
}

View File

@@ -12,6 +12,264 @@
#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(
@@ -39,7 +297,7 @@ EngpFileIoRequest(
/* Initialize an event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
/* Build IPR */
/* Build IRP */
liStartOffset.QuadPart = ullStartOffset;
pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
pDeviceObject,
@@ -113,7 +371,7 @@ EngFileIoControl(
/* Initialize an event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
/* Build IO control IPR */
/* Build IO control IRP */
pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode,
pDeviceObject,
lpInBuffer,

View File

@@ -18,8 +18,6 @@ VOID
NTAPI
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
{
HPALETTE hpal = NULL;
ASSERT(pebo);
ASSERT(pbrush);
ASSERT(pdc);
@@ -35,14 +33,11 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC 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)
{
@@ -80,7 +75,12 @@ EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor)
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);
@@ -109,8 +109,7 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
pebo->BrushObject.pvRbrush = NULL;
}
if (pebo->ppalSurf != &gpalRGB)
PALETTE_ShareUnlockPalette(pebo->ppalSurf);
PALETTE_ShareUnlockPalette(pebo->ppalSurf);
}
VOID
@@ -145,7 +144,7 @@ EngRealizeBrush(
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 */
@@ -192,12 +191,8 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
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;
@@ -210,16 +205,18 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
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,

View File

@@ -56,7 +56,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
{
/* 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;
}
@@ -64,7 +64,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
/* 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);
@@ -127,7 +127,6 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
&ClippedDestRect, &SrcPoint))
{
EngDeleteClip(EnterLeave->TrivialClipObj);
EngFreeMem((*ppsoOutput)->pvBits);
EngUnlockSurface(*ppsoOutput);
EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
return FALSE;
@@ -149,7 +148,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
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)
{
@@ -219,7 +218,6 @@ IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave)
Result = TRUE;
}
}
EngFreeMem(EnterLeave->OutputObj->pvBits);
EngUnlockSurface(EnterLeave->OutputObj);
EngDeleteSurface((HSURF)EnterLeave->OutputBitmap);
EngDeleteClip(EnterLeave->TrivialClipObj);

View File

@@ -548,14 +548,7 @@ IntEngGradientFill(
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,
@@ -566,8 +559,6 @@ IntEngGradientFill(
Ret = EngGradientFill(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents,
pptlDitherOrg, ulMode);
}
MouseSafetyOnDrawEnd(psoDest);
SURFACE_UnlockBitmapBits(psurf);
return Ret;
}

View File

@@ -0,0 +1,504 @@
/*
* 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);
}

View File

@@ -565,10 +565,7 @@ IntEngLineTo(SURFOBJ *psoDest,
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(
@@ -576,7 +573,7 @@ IntEngLineTo(SURFOBJ *psoDest,
}
#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 */
}
@@ -587,9 +584,6 @@ IntEngLineTo(SURFOBJ *psoDest,
ret = EngLineTo(psoDest, ClipObj, pbo, x1, y1, x2, y2, RectBounds, Mix);
}
MouseSafetyOnDrawEnd(psoDest);
SURFACE_UnlockBitmapBits(psurfDest);
return ret;
}

View File

@@ -3,7 +3,7 @@
* 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>
@@ -11,12 +11,348 @@
#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
@@ -25,9 +361,8 @@ EngLoadModuleForWrite(
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
@@ -36,17 +371,46 @@ EngMapModule(
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
@@ -56,8 +420,28 @@ EngMapFile(
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
@@ -65,8 +449,11 @@ APIENTRY
EngUnmapFile(
IN ULONG_PTR iFile)
{
UNIMPLEMENTED;
return FALSE;
HANDLE hModule = (HANDLE)iFile;
EngFreeModule(hModule);
return TRUE;
}
@@ -110,36 +497,3 @@ EngUnmapFontFile(
// 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;
}

View File

@@ -79,6 +79,7 @@ EngAllocUserMem(SIZE_T cj, ULONG Tag)
}
/* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */
//hSecure = EngSecureMem(NewMem, cj);
return NewMem;
}
@@ -166,6 +167,7 @@ HackUnsecureVirtualMemory(
HANDLE APIENTRY
EngSecureMem(PVOID Address, ULONG Length)
{
return (HANDLE)-1; // HACK!!!
return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE);
}
@@ -175,6 +177,7 @@ EngSecureMem(PVOID Address, ULONG Length)
VOID APIENTRY
EngUnsecureMem(HANDLE Mem)
{
if (Mem == (HANDLE)-1) return; // HACK!!!
MmUnsecureVirtualMemory((PVOID) Mem);
}

View File

@@ -37,23 +37,17 @@ EngSetPointerTag(
*/
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;
@@ -83,12 +77,12 @@ MouseSafetyOnDrawStart(
}
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);
@@ -99,19 +93,12 @@ MouseSafetyOnDrawStart(
*/
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;
@@ -125,7 +112,10 @@ MouseSafetyOnDrawEnd(
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;
@@ -175,18 +165,17 @@ IntHideMousePointer(
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
@@ -229,77 +218,72 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
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);
IntEngBitBlt(psoDest,
&pgp->psurfMask->SurfObj,
NULL,
NULL,
NULL,
&rclSurf,
(POINTL*)&rclPointer,
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCAND));
IntEngBitBltEx(psoDest,
&pgp->psurfColor->SurfObj,
NULL,
NULL,
NULL,
&rclSurf,
(POINTL*)&rclPointer,
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCINVERT),
FALSE);
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));
}
}
@@ -353,7 +337,7 @@ EngSetPointerShape(
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. */
@@ -373,10 +357,10 @@ EngSetPointerShape(
/* 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;
@@ -540,28 +524,13 @@ EngMovePointer(
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,
@@ -576,13 +545,11 @@ IntEngSetPointerShape(
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,
@@ -620,8 +587,6 @@ IntEngSetPointerShape(
ppdev->pfnMovePointer = EngMovePointer;
}
SURFACE_UnlockBitmapBits(psurf);
return ulResult;
}
@@ -649,10 +614,14 @@ GreSetPointerShape(
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;
}
@@ -668,7 +637,7 @@ GreSetPointerShape(
{
/* We have one, lock it */
psurfColor = SURFACE_ShareLockSurface(hbmColor);
if (psurfColor)
{
/* Create an XLATEOBJ, no mono support */
@@ -700,6 +669,8 @@ GreSetPointerShape(
if (psurfMask)
SURFACE_ShareUnlockSurface(psurfMask);
EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
/* Unlock the DC */
DC_UnlockDc(pdc);
@@ -724,12 +695,23 @@ GreMovePointer(
DPRINT1("Failed to lock the DC.\n");
return;
}
ASSERT(pdc->dctype == DCTYPE_DIRECT);
/* Store the cursor exclude position in the PDEV */
prcl = &pdc->ppdev->Pointer.Exclude;
/* Acquire PDEV lock */
EngAcquireSemaphore(pdc->ppdev->hsemDevLock);
/* Call Eng/Drv function */
IntEngMovePointer(&pdc->dclevel.pSurface->SurfObj, x, y, prcl);
/* 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);
}
/* Release PDEV lock */
EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
/* Unlock the DC */
DC_UnlockDc(pdc);

View File

@@ -32,14 +32,13 @@
#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++)
@@ -47,22 +46,9 @@ static BOOL APIENTRY FillSolidUnlocked(SURFOBJ *pso, PRECTL pRect, ULONG iColor)
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)
@@ -85,7 +71,7 @@ EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
if (ClipRegion->iDComplexity == DC_RECT)
{
FillSolidUnlocked(pso, &(ClipRegion->rclBounds), iColor);
FillSolid(pso, &(ClipRegion->rclBounds), iColor);
} else {
/* Enumerate all the rectangles and draw them */
@@ -94,7 +80,7 @@ EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
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);
}
@@ -136,18 +122,11 @@ IntEngPaint(IN SURFOBJ *pso,
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 );

View File

@@ -0,0 +1,844 @@
/*
* 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;
}

View File

@@ -0,0 +1,99 @@
/*
* 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;
}

View File

@@ -69,6 +69,19 @@ EngReleaseSemaphore ( IN HSEMAPHORE hsem )
IntGdiReleaseSemaphore ( hsem );
}
VOID
NTAPI
EngAcquireSemaphoreShared(
IN HSEMAPHORE hsem)
{
PTHREADINFO pti;
ASSERT(hsem);
ExEnterCriticalRegionAndAcquireResourceShared((PERESOURCE)hsem);
pti = PsGetThreadWin32Thread(PsGetCurrentThread());
if (pti) ++pti->dwEngAcquireCount;
}
/*
* @implemented
*/

View File

@@ -462,25 +462,16 @@ IntEngStretchBlt(SURFOBJ *psoDest,
/* 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,
@@ -514,17 +505,6 @@ IntEngStretchBlt(SURFOBJ *psoDest,
ROP);
}
if (UsesSource)
{
MouseSafetyOnDrawEnd(psoSource);
if (psoSource != psoDest)
{
SURFACE_UnlockBitmapBits(psurfSource);
}
}
MouseSafetyOnDrawEnd(psoDest);
SURFACE_UnlockBitmapBits(psurfDest);
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@@ -76,7 +76,7 @@ EngTransparentBlt(SURFOBJ *psoDest,
OutputRect.top = DestRect->bottom;
OutputRect.bottom = DestRect->top;
}
if(Clip)
{
if(OutputRect.left < Clip->rclBounds.left)
@@ -284,17 +284,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
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,
@@ -309,14 +299,6 @@ IntEngTransparentBlt(SURFOBJ *psoDest,
&OutputRect, &InputRect, iTransColor, Reserved);
}
MouseSafetyOnDrawEnd(psoDest);
SURFACE_UnlockBitmapBits(psurfDest);
if(psoSource != psoDest)
{
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource);
}
return Ret;
}

View File

@@ -64,7 +64,7 @@ EXLATEOBJ_iXlateRGBtoBGR(PEXLATEOBJ pxlo, ULONG iColor)
{
ULONG iNewColor;
/* Copy green and alpha */
/* Copy green */
iNewColor = iColor & 0xff00ff00;
/* Mask red and blue */
@@ -362,19 +362,19 @@ EXLATEOBJ_vInitialize(
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];
@@ -391,10 +391,10 @@ EXLATEOBJ_vInitialize(
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;
@@ -406,28 +406,28 @@ EXLATEOBJ_vInitialize(
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);
@@ -437,7 +437,7 @@ EXLATEOBJ_vInitialize(
pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor);
}
}
else if (ppalSrc->Mode & PAL_INDEXED)
else if (ppalSrc->flFlags & PAL_INDEXED)
{
cEntries = ppalSrc->NumColors;
@@ -458,7 +458,7 @@ EXLATEOBJ_vInitialize(
pexlo->xlo.cEntries = cEntries;
pexlo->pfnXlate = EXLATEOBJ_iXlateTable;
if (ppalDst->Mode & PAL_INDEXED)
if (ppalDst->flFlags & PAL_INDEXED)
{
pexlo->xlo.flXlate |= XO_TABLE;
@@ -504,78 +504,78 @@ EXLATEOBJ_vInitialize(
}
}
}
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;
@@ -603,157 +603,24 @@ EXLATEOBJ_vInitXlateFromDCs(
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
@@ -827,9 +694,9 @@ XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut)
/* 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;
}
@@ -840,7 +707,7 @@ XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut)
}
/* 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++)

View File

@@ -2,11 +2,47 @@
#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);

View File

@@ -1,4 +1,5 @@
#pragma once
#ifndef __WIN32K_DC_H
#define __WIN32K_DC_H
typedef struct _DC *PDC;
@@ -22,6 +23,30 @@ 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
@@ -29,7 +54,7 @@ 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;
@@ -136,13 +161,12 @@ extern PDC defaultDCstate;
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);
@@ -155,10 +179,16 @@ VOID FASTCALL DC_vUpdateFillBrush(PDC pdc);
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);
@@ -174,12 +204,9 @@ VOID FASTCALL IntGdiUnreferencePdev(PPDEVOBJ pPDev, DWORD CleanUpType);
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)
@@ -228,5 +255,6 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal)
pdc->dclevel.ppal = ppal;
}
BOOL FASTCALL IntPrepareDriverIfNeeded(VOID);
extern PDEVOBJ PrimarySurface;
extern PBRUSH pbrDefaultBrush ;
#endif /* not __WIN32K_DC_H */

View File

@@ -0,0 +1,57 @@
//#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;

View File

@@ -5,15 +5,17 @@
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);

View File

@@ -21,3 +21,19 @@ IntEngWindowChanged(
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);

View File

@@ -71,6 +71,7 @@ VOID INTERNAL_CALL GDIOBJ_FreeObj (POBJ pObj, UCHAR ObjectType);
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);

View File

@@ -45,7 +45,7 @@ IntEngLineTo(SURFOBJ *Surface,
MIX mix);
BOOL APIENTRY
IntEngBitBltEx(SURFOBJ *DestObj,
IntEngBitBlt(SURFOBJ *DestObj,
SURFOBJ *SourceObj,
SURFOBJ *Mask,
CLIPOBJ *ClipRegion,
@@ -55,14 +55,7 @@ IntEngBitBltEx(SURFOBJ *DestObj,
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,

View File

@@ -167,9 +167,6 @@ IntGetSysColor(INT nIndex);
/* Other Stuff */
INT FASTCALL
IntGdiGetDeviceCaps(PDC dc, INT Index);
INT
FASTCALL
IntGdiEscape(PDC dc,
@@ -186,14 +183,6 @@ IntEnumDisplaySettings(
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,

View File

@@ -0,0 +1,86 @@
#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);

View File

@@ -29,6 +29,33 @@ VOID FASTCALL IntUserManualGuiCheck(LONG Check);
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(

View File

@@ -2,8 +2,8 @@
#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)

View File

@@ -40,7 +40,7 @@ typedef struct _PALETTE
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;
@@ -52,8 +52,8 @@ typedef struct _PALETTE
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,

View File

@@ -1,6 +1,5 @@
#pragma once
#include <drivers/directx/directxint.h>
#ifndef __WIN32K_PDEVOBJ_H
#define __WIN32K_PDEVOBJ_H
/* PDEVOBJ flags */
#define PDEV_DISPLAY 0x00000001 /* Display device */
@@ -37,6 +36,21 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
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];
@@ -48,15 +62,17 @@ typedef struct _GRAPHICS_DEVICE
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
@@ -64,8 +80,8 @@ typedef struct _PDEVOBJ
BASEOBJECT BaseObject;
struct _PDEVOBJ * ppdevNext;
INT cPdevRefs;
INT cPdevOpenRefs;
LONG cPdevRefs;
LONG cPdevOpenRefs;
struct _PDEVOBJ * ppdevParent;
FLONG flFlags; // flags
// FLONG flAccelerated;
@@ -98,17 +114,17 @@ typedef struct _PDEVOBJ
// 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;
@@ -117,15 +133,12 @@ typedef struct _PDEVOBJ
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?
@@ -134,13 +147,47 @@ typedef struct _PDEVOBJ
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 ********************************************************************/
PSIZEL FASTCALL PDEV_sizl(PPDEVOBJ, PSIZEL);
extern PPDEVOBJ gppdevPrimary;
#define pPrimarySurface gppdevPrimary
extern ULONG gdwDirectDrawContext;
/* 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
PDEVOBJ_sizl(PPDEVOBJ, PSIZEL);
#endif /* !__WIN32K_PDEVOBJ_H */

View File

@@ -14,7 +14,7 @@ typedef struct _ROSRGNDATA
RGNDATAHEADER rdh;
RECTL *Buffer;
} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA;
} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA, REGION, *PREGION;
/* Functions ******************************************************************/

View File

@@ -8,48 +8,88 @@
/* GDI surface object */
typedef struct _SURFACE
{
BASEOBJECT BaseObject;
BASEOBJECT BaseObject;
SURFOBJ SurfObj;
FLONG flHooks;
FLONG flFlags;
struct _PALETTE *ppal;
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
};
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
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)
@@ -64,15 +104,31 @@ typedef struct _SURFACE
#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)

View File

@@ -78,4 +78,6 @@
#include <include/gdifloat.h>
#include <include/engobjects.h>
#include <include/engevent.h>
#include <include/ldevobj.h>
#include <include/device.h>
#include <dib/dib.h>

View File

@@ -45,7 +45,6 @@ DbgCmpXlate(XLATEOBJ *pxlo1, XLATEOBJ *pxlo2);
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);

View File

@@ -1,264 +0,0 @@
/*
* 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 */

View File

@@ -34,8 +34,6 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
PSECTION_OBJECT GdiTableSection = NULL;
LIST_ENTRY GlobalDriverListHead;
HANDLE GlobalUserHeap = NULL;
PSECTION_OBJECT GlobalUserHeapSection = NULL;
@@ -368,6 +366,7 @@ Win32kInitWin32Thread(PETHREAD Thread)
return(STATUS_SUCCESS);
}
C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE);
/*
* This definition doesn't work
@@ -423,8 +422,19 @@ DriverEntry (
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();
@@ -435,6 +445,26 @@ DriverEntry (
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))
{
@@ -526,13 +556,6 @@ DriverEntry (
return(Status);
}
Status = InitDcImpl();
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to initialize Device context implementation!\n");
return STATUS_UNSUCCESSFUL;
}
/* Initialize FreeType library */
if (! InitFontSupport())
{
@@ -540,13 +563,6 @@ DriverEntry (
return STATUS_UNSUCCESSFUL;
}
InitXlateImpl();
/* Create stock objects, ie. precreated objects commonly
used by win32 applications */
CreateStockObjects();
CreateSysColorObjects();
gusLanguageID = IntGdiGetLanguageID();
return STATUS_SUCCESS;

View File

@@ -5,7 +5,7 @@ NTSTATUS _MmCopyFromCaller( PVOID Target, PVOID Source, UINT Bytes ) {
_SEH2_TRY
{
/* ProbeForRead(Source,Bytes,1); */
ProbeForRead(Source,Bytes,1);
RtlCopyMemory(Target,Source,Bytes);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)

View File

@@ -1,621 +1 @@
/*
* 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 */

View File

@@ -149,213 +149,98 @@ W32kMapViewOfSection(
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;
{
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);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
_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))
if(!NT_SUCCESS(Status))
{
DPRINT1("Bad File?\n");
goto leave;
}
if (pbmfh->bfType == 0x4D42 /* 'BM' */)
{
cjInfoSize = bmiLocal.bmiHeader.bV5Size +
bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD);
pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize);
/* Could be BITMAPCOREINFO */
BITMAPINFO* pConvertedInfo;
HDC hdc;
// 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);
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);

View File

@@ -11,6 +11,134 @@
#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(
@@ -163,7 +291,8 @@ RegWriteUserSetting(
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;
}

View File

@@ -1,4 +1,4 @@
/*
/*
* PROJECT: ReactOS Win32 Subsystem
* LICENSE: GPL - See COPYING in the top level directory
* FILE: subsystems/win32/win32k/ntddraw/dxeng.c
@@ -297,8 +297,7 @@ DxEngGetHdevData(HDEV hDev,
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");

View File

@@ -243,34 +243,62 @@ IntEmptyClipboardData(VOID)
/*==============================================================*/
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;
/* 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
offset = sizeof(BITMAPINFOHEADER) + ((ih->biBitCount <= 8) ? (sizeof(RGBQUAD) * (1 << ih->biBitCount)) : 0);
if(!NT_SUCCESS(Status))
{
UserReleaseDC(ClipboardWindow, hdc, FALSE);
return NULL;
}
hbitmap = NtGdiCreateDIBitmapInternal(hdc,
ih->biWidth,
ih->biHeight,
CBM_INIT,
(LPBYTE)ih+offset,
(LPBITMAPINFO)ih,
DIB_RGB_COLORS,
ih->biBitCount,
ih->biSizeImage,
0,
0);
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;
}

View File

@@ -109,7 +109,7 @@ UserSetCursor(
PCURICON_OBJECT OldCursor;
HCURSOR hOldCursor = (HCURSOR)0;
HDC hdcScreen;
CurInfo = IntGetSysCursorInfo();
OldCursor = CurInfo->CurrentCursorObject;
@@ -483,6 +483,7 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
}
/*
* @implemented
*/
@@ -692,6 +693,35 @@ CLEANUP:
END_CLEANUP;
}
BOOL
APIENTRY
UserClipCursor(
RECTL *prcl)
{
/* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
PSYSTEM_CURSORINFO CurInfo;
PWND DesktopWindow = NULL;
CurInfo = IntGetSysCursorInfo();
DesktopWindow = UserGetDesktopWindow();
if (prcl != NULL &&
(prcl->right > prcl->left) &&
(prcl->bottom > prcl->top) &&
DesktopWindow != NULL)
{
CurInfo->bClipped = TRUE;
RECTL_bIntersectRect(&CurInfo->rcClip, prcl, &DesktopWindow->rcWindow);
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
}
else
{
CurInfo->bClipped = FALSE;
}
return TRUE;
}
/*
* @implemented
@@ -699,45 +729,37 @@ CLEANUP:
BOOL
APIENTRY
NtUserClipCursor(
RECTL *UnsafeRect)
RECTL *prcl)
{
/* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
PSYSTEM_CURSORINFO CurInfo;
RECTL Rect;
PWND DesktopWindow = NULL;
DECLARE_RETURN(BOOL);
RECTL rclLocal;
BOOL bResult;
DPRINT("Enter NtUserClipCursor\n");
UserEnterExclusive();
if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
if (prcl)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
RETURN(FALSE);
_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
prcl = &rclLocal;
}
UserEnterExclusive();
CurInfo = IntGetSysCursorInfo();
/* Call the internal function */
bResult = UserClipCursor(prcl);
DesktopWindow = UserGetDesktopWindow();
if ((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
&& DesktopWindow && UnsafeRect != NULL)
{
CurInfo->bClipped = TRUE;
RECTL_bIntersectRect(&CurInfo->rcClip, &Rect, &DesktopWindow->rcWindow);
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
RETURN(TRUE);
}
CurInfo->bClipped = FALSE;
RETURN(TRUE);
CLEANUP:
DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
return bResult;
}
@@ -937,12 +959,12 @@ NtUserSetCursorContents(
/* 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);
}
@@ -968,8 +990,8 @@ NtUserSetCursorContents(
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;
@@ -1287,23 +1309,12 @@ UserDrawIconEx(
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)
{
@@ -1317,35 +1328,22 @@ UserDrawIconEx(
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 = ptr[3];
ptr[0] = (ptr[0] * Alpha) / 0xff;
ptr[1] = (ptr[1] * Alpha) / 0xff;
ptr[2] = (ptr[2] * Alpha) / 0xff;
Alpha = ((BYTE)(Pixel >> 24) & 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);
@@ -1364,12 +1362,10 @@ UserDrawIconEx(
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);

View File

@@ -616,8 +616,6 @@ UserRedrawDesktop()
{
PWND Window = NULL;
UserEnterExclusive();
Window = UserGetDesktopWindow();
IntInvalidateWindows( Window,
@@ -626,7 +624,6 @@ UserRedrawDesktop()
RDW_ERASE |
RDW_INVALIDATE |
RDW_ALLCHILDREN);
UserLeave();
}

File diff suppressed because it is too large Load Diff

View File

@@ -163,10 +163,7 @@ static BOOL UserLoadKbdDll(WCHAR *wsKLID,
DPRINT("Loaded %wZ\n", &FullLayoutPath);
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
LdrGetProcedureAddress((*(PDRIVERS*)phModule)->BaseAddress,
&kbdProcedureName,
0,
(PVOID*)&layerDescGetFn);
layerDescGetFn = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor");
if(layerDescGetFn)
{

View File

@@ -395,12 +395,12 @@ IntDispatchMessage(PMSG pMsg)
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;
@@ -631,7 +631,7 @@ co_IntTranslateMouseMessage(
}
}
if ( gspv.bMouseClickLock &&
if ( gspv.bMouseClickLock &&
( (Msg->message == WM_LBUTTONUP) ||
(Msg->message == WM_LBUTTONDOWN) ) )
{
@@ -867,98 +867,98 @@ co_IntPeekMessage( PUSER_MESSAGE Msg,
do
{
KeQueryTickCount(&LargeTickCount);
ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
KeQueryTickCount(&LargeTickCount);
ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
/* Dispatch sent messages here. */
while (co_MsqDispatchOneSentMessage(ThreadQueue))
;
/* Dispatch sent messages here. */
while (co_MsqDispatchOneSentMessage(ThreadQueue))
;
/* Now look for a quit message. */
/* 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;
}
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 paint messages. */
if( IntGetPaintMessage( Window,
MsgFilterMin,
MsgFilterMax,
pti,
&Msg->Msg,
RemoveMessages))
{
break;
}
if (PostTimerMessages(Window))
{
continue;
}
return FALSE;
}
/* Check for sent messages again. */
while (co_MsqDispatchOneSentMessage(ThreadQueue))
;
/* Check for paint messages. */
if( IntGetPaintMessage( Window,
MsgFilterMin,
MsgFilterMax,
pti,
&Msg->Msg,
RemoveMessages))
{
break;
}
if (PostTimerMessages(Window))
{
continue;
}
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
@@ -1240,7 +1240,7 @@ UserPostMessage( HWND Wnd,
return FALSE;
}
if (!Wnd)
if (!Wnd)
return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
Msg,
wParam,
@@ -1257,6 +1257,7 @@ UserPostMessage( HWND Wnd,
if (List != NULL)
{
UserPostMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
UserPostMessage(List[i], Msg, wParam, lParam);
ExFreePool(List);
@@ -1419,14 +1420,14 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
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) &&
@@ -1485,6 +1486,9 @@ co_IntSendMessageTimeout( HWND hWnd,
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)
{
@@ -1830,6 +1834,7 @@ UserSendNotifyMessage( HWND hWnd,
if (List != NULL)
{
UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
{
UserSendNotifyMessage(List[i], Msg, wParam, lParam);
@@ -2422,7 +2427,7 @@ NtUserDispatchMessage(PMSG UnsafeMsgInfo)
BOOL Hit = FALSE;
MSG SafeMsg;
UserEnterExclusive();
UserEnterExclusive();
_SEH2_TRY
{
ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
@@ -2434,7 +2439,7 @@ NtUserDispatchMessage(PMSG UnsafeMsgInfo)
Hit = TRUE;
}
_SEH2_END;
if (!Hit) Res = IntDispatchMessage(&SafeMsg);
UserLeave();
@@ -2677,11 +2682,11 @@ NtUserMessageCall(
{
BadChk = TRUE;
}
_SEH2_END;
_SEH2_END;
}
break;
default:
break;
break;
}
UserLeave();

View File

@@ -24,9 +24,19 @@ FASTCALL
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;

View File

@@ -199,39 +199,6 @@ NtUserDrawAnimatedRects(
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(

View File

@@ -73,16 +73,6 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
return Status;
}
if (!gpsi)
{
gpsi = UserHeapAlloc(sizeof(SERVERINFO));
if (gpsi)
{
RtlZeroMemory(gpsi, sizeof(SERVERINFO));
DPRINT("Global Server Data -> %x\n", gpsi);
}
}
InitUserAtoms();
InitSysParams();
@@ -90,6 +80,8 @@ NTSTATUS FASTCALL InitUserImpl(VOID)
return STATUS_SUCCESS;
}
BOOL
InitVideo(ULONG);
NTSTATUS
NTAPI
@@ -100,6 +92,7 @@ UserInitialize(
// 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.
@@ -139,8 +132,8 @@ NtUserInitialize(
{
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)

View File

@@ -41,6 +41,9 @@ DceCreateDisplayDC(VOID)
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!
//

View File

@@ -31,7 +31,7 @@ BOOL FASTCALL IntDrawArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, d
static
BOOL
FASTCALL
IntArc( DC *dc,
IntArc( DC *dc,
int Left,
int Top,
int Right,
@@ -91,7 +91,7 @@ IntArc( DC *dc,
}
if (!PenWidth) PenWidth = 1;
pbrushPen->ptPenWidth.x = PenWidth;
pbrushPen->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.right = Right;
@@ -105,7 +105,7 @@ IntArc( DC *dc,
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;
@@ -172,7 +172,7 @@ IntArc( DC *dc,
}
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");
@@ -219,12 +219,6 @@ IntGdiArcInternal(
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)
@@ -329,7 +323,14 @@ NtGdiAngleArc(
}
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;
}
@@ -364,6 +365,15 @@ NtGdiArcInternal(
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,
@@ -376,6 +386,7 @@ NtGdiArcInternal(
XEndArc,
YEndArc);
DC_vFinishBlit(dc, NULL);
DC_UnlockDc( dc );
return Ret;
}

View File

@@ -42,6 +42,8 @@ NtGdiAlphaBlend(
{
PDC DCDest;
PDC DCSrc;
HDC ahDC[2];
PGDIOBJ apObj[2];
SURFACE *BitmapDest, *BitmapSrc;
RECTL DestRect, SourceRect;
BOOL bResult;
@@ -55,45 +57,30 @@ NtGdiAlphaBlend(
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;
@@ -121,35 +108,35 @@ NtGdiAlphaBlend(
!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,
@@ -159,9 +146,11 @@ NtGdiAlphaBlend(
&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;
}
@@ -182,59 +171,64 @@ NtGdiBitBlt(
{
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;
@@ -255,8 +249,19 @@ NtGdiBitBlt(
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)
@@ -291,14 +296,15 @@ NtGdiBitBlt(
&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;
}
@@ -318,97 +324,38 @@ NtGdiTransparentBlt(
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)
if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO)
{
DCSrc = DCDest;
}
if (DCSrc->dctype == DC_TYPE_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;
@@ -431,17 +378,39 @@ NtGdiTransparentBlt(
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;
}
@@ -674,6 +643,8 @@ GreStretchBltMask(
PDC DCDest;
PDC DCSrc = NULL;
PDC DCMask = NULL;
HDC ahDC[3];
PGDIOBJ apObj[3];
PDC_ATTR pdcattr;
SURFACE *BitmapDest, *BitmapSrc = NULL;
SURFACE *BitmapMask = NULL;
@@ -692,52 +663,59 @@ GreStretchBltMask(
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;
@@ -767,6 +745,12 @@ GreStretchBltMask(
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)
@@ -787,28 +771,25 @@ GreStretchBltMask(
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 */
@@ -823,13 +804,14 @@ GreStretchBltMask(
&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);
}
@@ -889,19 +871,12 @@ IntPatBlt(
{
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;
@@ -939,6 +914,13 @@ IntPatBlt(
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(
@@ -950,10 +932,12 @@ IntPatBlt(
&DestRect,
NULL,
NULL,
&eboFill.BrushObject, // use pDC->eboFill
&eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(dwRop));
DC_vFinishBlit(pdc, NULL);
EBRUSHOBJ_vCleanup(&eboFill);
return ret;

View File

@@ -22,110 +22,198 @@
#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)
return Bytes;
}
void
NTAPI
UnsafeSetBitmapBits(
PSURFACE psurf,
IN ULONG cjBits,
IN PVOID 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 */
pjDst = psurf->SurfObj.pvScan0;
pjSrc = pvBits;
lDeltaDst = psurf->SurfObj.lDelta;
lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
while (nHeight--)
{
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
Width, Height, BitsPixel);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
/* Copy one line */
memcpy(pjDst, pjSrc, lDeltaSrc);
pjSrc += lDeltaSrc;
pjDst += lDeltaDst;
}
WidthBytes = BITMAP_GetWidthBytes(Width, BitsPixel);
}
Size.cx = Width;
Size.cy = abs(Height);
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;
/* Make sure that cjBits will not overflow */
if ((ULONGLONG)WidthBytes * Size.cy >= 0x100000000ULL)
/* Verify format */
if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
/* Allocate a surface */
psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
if (!psurf)
{
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
Width, Height, BitsPixel);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
/* 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)
{
DPRINT("IntGdiCreateBitmap: returned 0\n");
return 0;
}
psurfBmp = SURFACE_LockSurface(hBitmap);
if (psurfBmp == NULL)
{
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)
{
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)
{
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
nWidth, nHeight, cBitsPixel);
EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/* 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)
{
BOOL Hit = FALSE;
UINT cjBits = BITMAP_GetWidthBytes(Width, BitsPixel) * abs(Height);
// FIXME: Use MmSecureVirtualMemory
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,
@@ -143,11 +231,21 @@ IntCreateCompatibleBitmap(
{
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
{
@@ -160,83 +258,71 @@ IntCreateCompatibleBitmap(
{
if (Count == sizeof(BITMAP))
{
/* We have a bitmap bug!!! W/O the HACK, we have white icons.
PSURFACE psurfBmp;
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);
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;
BITMAPINFO* bi = (BITMAPINFO*)buf;
/* 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);
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)
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
{
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;
/* Copy the color masks */
RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
}
else if (bi->bmiHeader.biBitCount <= 8)
{
/* Copy the color table */
UINT Index;
PPALETTE PalGDI;
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
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,
@@ -245,8 +331,6 @@ IntCreateCompatibleBitmap(
NULL,
0,
0);
ExFreePoolWithTag(bi, TAG_TEMP);
return Bmp;
}
}
@@ -272,7 +356,7 @@ NtGdiCreateCompatibleBitmap(
}
if (!hDC)
return IntGdiCreateBitmap(Width, Height, 1, 1, 0);
return GreCreateBitmap(Width, Height, 1, 1, 0);
Dc = DC_LockDc(hDC);
@@ -313,7 +397,7 @@ NtGdiGetBitmapDimension(
_SEH2_TRY
{
ProbeForWrite(Dimension, sizeof(SIZE), 1);
*Dimension = psurfBmp->dimension;
*Dimension = psurfBmp->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -334,8 +418,6 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
BOOL bInRect = FALSE;
SURFACE *psurf;
SURFOBJ *pso;
HPALETTE hpal = 0;
PPALETTE ppal;
EXLATEOBJ exlo;
HBITMAP hBmpTmp;
@@ -361,21 +443,8 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
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
{
@@ -385,7 +454,6 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
}
EXLATEOBJ_vCleanup(&exlo);
PALETTE_ShareUnlockPalette(ppal);
}
}
DC_UnlockDc(dc);
@@ -412,7 +480,7 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
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);
@@ -482,6 +550,36 @@ IntGetBitmapBits(
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,
@@ -503,7 +601,7 @@ NtGdiGetBitmapBits(
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);
@@ -521,7 +619,8 @@ NtGdiGetBitmapBits(
_SEH2_TRY
{
ProbeForWrite(pUnsafeBits, Bytes, 1);
ret = IntGetBitmapBits(psurf, Bytes, pUnsafeBits);
UnsafeGetBitmapBits(psurf, Bytes, pUnsafeBits);
ret = Bytes;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -535,46 +634,6 @@ NtGdiGetBitmapBits(
}
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,
@@ -599,7 +658,8 @@ NtGdiSetBitmapBits(
_SEH2_TRY
{
ProbeForRead(pUnsafeBits, Bytes, 1);
ret = IntSetBitmapBits(psurf, Bytes, pUnsafeBits);
UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
ret = 1;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -637,7 +697,7 @@ NtGdiSetBitmapDimension(
_SEH2_TRY
{
ProbeForWrite(Size, sizeof(SIZE), 1);
*Size = psurf->dimension;
*Size = psurf->sizlDim;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -647,8 +707,8 @@ NtGdiSetBitmapDimension(
}
/* 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);
@@ -665,7 +725,7 @@ VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color)
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);
}
@@ -707,7 +767,7 @@ VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color)
default:
DPRINT("Unsupported color type %d passed\n", *Color >> 24);
break;
}
}
}
BOOL APIENTRY
@@ -786,40 +846,6 @@ BITMAP_GetRealBitsPixel(UINT nBitsPixel)
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)
{
@@ -833,7 +859,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
return 0;
}
Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP);
Bitmap = SURFACE_LockSurface(hBitmap);
if (Bitmap == NULL)
{
return 0;
@@ -846,34 +872,23 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
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
{
@@ -882,7 +897,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
}
}
GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
SURFACE_UnlockSurface(Bitmap);
return res;
}
@@ -900,15 +915,17 @@ BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
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))
{
@@ -920,38 +937,44 @@ BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
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;
@@ -975,14 +998,15 @@ APIENTRY
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 */

View File

@@ -1,9 +1,9 @@
/*
/*
* 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>
@@ -19,13 +19,13 @@ typedef struct _GDI_OBJ_ATTR_FREELIST
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 */
@@ -46,7 +46,7 @@ AllocateObjectAttr(VOID)
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry;
int i;
pti = PsGetCurrentThreadWin32Thread();
if (pti->pgdiBrushAttr)
{
@@ -127,9 +127,9 @@ FreeObjectAttr(PVOID pAttr)
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;
@@ -244,129 +244,6 @@ BRUSH_GetObject(PBRUSH pbrush, INT Count, LPLOGBRUSH Buffer)
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(
@@ -379,9 +256,7 @@ IntGdiCreateDIBBrush(
PBRUSH pbrush;
HBITMAP hPattern;
ULONG_PTR DataPtr;
UINT PaletteEntryCount;
PSURFACE psurfPattern;
INT PaletteType;
PVOID pvDIBits;
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
{
@@ -389,36 +264,19 @@ IntGdiCreateDIBBrush(
return NULL;
}
if (!CalculateColorTableSize(&BitmapInfo->bmiHeader,
&ColorSpec,
&PaletteEntryCount))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
// 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);
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)
@@ -455,7 +313,7 @@ IntGdiCreateHatchBrush(
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);

View File

@@ -28,27 +28,16 @@ CLIPPING_UpdateGCRegion(DC* Dc)
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 ;
}
@@ -62,28 +51,27 @@ CLIPPING_UpdateGCRegion(DC* Dc)
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);
}
@@ -115,7 +103,6 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn)
NtGdiOffsetRgn(dc->prgnVis->BaseObject.hHmgr, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
CLIPPING_UpdateGCRegion(dc);
}
DC_UnlockDc(dc);
return retval;
@@ -166,6 +153,7 @@ int FASTCALL GdiExtSelectClipRgn(PDC dc,
else
NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode);
}
return CLIPPING_UpdateGCRegion(dc);
}
@@ -233,6 +221,7 @@ GdiGetClipBox(HDC hDC, PRECTL rc)
retval = REGION_GetRgnBox(pRgnNew, rc);
REGION_FreeRgnByHandle(pRgnNew->BaseObject.hHmgr);
DC_UnlockDc(dc);
if(Unlock) REGION_UnlockRgn(pRgn);
return retval;
@@ -529,6 +518,7 @@ IntGdiSetMetaRgn(PDC pDC)
return Ret;
}
int APIENTRY NtGdiSetMetaRgn(HDC hDC)
{
INT Ret;
@@ -570,7 +560,7 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC)
IntGdiCombineRgn( pDC->prgnAPI,
pDC->dclevel.prgnClip,
pDC->dclevel.prgnMeta,
RGN_AND );
RGN_AND);
}
else
{
@@ -579,43 +569,42 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC)
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;
}

View File

@@ -152,35 +152,49 @@ FreeDcAttr(PDC_ATTR pDc_Attr)
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
}
@@ -188,23 +202,37 @@ DC_AllocateDcAttr(HDC hDC)
}
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;
}
}
}
@@ -218,12 +246,8 @@ CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr)
_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)
{

File diff suppressed because it is too large Load Diff

View File

@@ -110,8 +110,10 @@ DC_vUpdateTextBrush(PDC pdc)
{
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);
@@ -127,7 +129,7 @@ DC_vUpdateBackgroundBrush(PDC pdc)
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);
@@ -164,7 +166,7 @@ GdiSelectPalette(
/* 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 */
@@ -282,14 +284,24 @@ NtGdiSelectBitmap(
}
/* 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,
@@ -356,6 +368,7 @@ NtGdiSelectClipPath(
if (pPath->state != PATH_Closed)
{
SetLastWin32Error(ERROR_CAN_NOT_COMPLETE);
DC_UnlockDc(pdc);
return FALSE;
}

View File

@@ -15,9 +15,14 @@ VOID
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....
@@ -36,7 +41,6 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
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);
@@ -91,16 +95,96 @@ NtGdiResetDC(
}
VOID
NTAPI
DC_vRestoreDC(
IN PDC pdc,
INT iSaveLevel)
{
PEPROCESS pepCurrentProcess;
HDC hdcSave;
PDC pdcSave;
ASSERT(iSaveLevel > 0);
DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel);
/* 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 (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess))
{
/* Could not get ownership. That's bad! */
DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n",
hdcSave, pdc->BaseObject.hHmgr);
return;// FALSE;
}
/* Lock the saved dc */
pdcSave = DC_LockDc(hdcSave);
if (!pdcSave)
{
/* WTF? Internal error! */
DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
hdcSave, pdc->BaseObject.hHmgr);
return;// FALSE;
}
/* Remove the saved dc from the queue */
pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave;
/* Decrement save level */
pdc->dclevel.lSaveDepth--;
/* Is this the state we want? */
if (pdc->dclevel.lSaveDepth == iSaveLevel)
{
/* 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)
{
PATH_Delete(pdc->dclevel.hPath);
pdc->dclevel.hPath = 0;
pdc->dclevel.flPath &= ~DCPATH_SAVE;
}
}
/* 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, pdcSave;
HDC hdcSave;
PDC pdc;
DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel);
DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel);
/* Lock the original DC */
pdc = DC_LockDc(hdc);
@@ -126,67 +210,12 @@ NtGdiRestoreDC(
return FALSE;
}
/* Loop the save levels */
while (pdc->dclevel.lSaveDepth > iSaveLevel)
{
hdcSave = pdc->dclevel.hdcSave;
/* Set us as the owner */
if (!IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_POWNED, FALSE ))
{
/* Could not get ownership. That's bad! */
DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n",
hdcSave, hdc);
return FALSE;
}
/* Lock the saved dc */
pdcSave = DC_LockDc(hdcSave);
if (!pdcSave)
{
/* WTF? Internal error! */
DPRINT1("Could not lock the saved DC (%p) for dc %p!\n",
hdcSave, hdc);
DC_UnlockDc(pdc);
return FALSE;
}
/* Remove the saved dc from the queue */
pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave;
/* Decrement save level */
pdc->dclevel.lSaveDepth--;
/* Is this the state we want? */
if (pdc->dclevel.lSaveDepth == iSaveLevel)
{
/* Copy the state back */
DC_vCopyState(pdcSave, pdc, FALSE);
// 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)
{
PATH_Delete(pdc->dclevel.hPath);
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!
}
/* Delete the saved dc */
GreDeleteObject(hdcSave);
}
/* Call the internal function */
DC_vRestoreDC(pdc, iSaveLevel);
DC_UnlockDc(pdc);
DPRINT("Leaving NtGdiRestoreDC\n");
DPRINT("Leave NtGdiRestoreDC\n");
return TRUE;
}
@@ -200,7 +229,7 @@ NtGdiSaveDC(
PDC pdc, pdcSave;
INT lSaveDepth;
DPRINT("NtGdiSaveDC(%lx)\n", hDC);
DPRINT("NtGdiSaveDC(%p)\n", hDC);
/* Lock the original dc */
pdc = DC_LockDc(hDC);
@@ -212,7 +241,7 @@ NtGdiSaveDC(
}
/* Allocate a new dc */
pdcSave = DC_AllocDC(NULL);
pdcSave = DC_AllocDcWithHandle();
if (pdcSave == NULL)
{
DPRINT("Could not allocate a new DC\n");
@@ -221,12 +250,25 @@ NtGdiSaveDC(
}
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;
@@ -243,7 +285,7 @@ NtGdiSaveDC(
DC_UnlockDc(pdcSave);
DC_UnlockDc(pdc);
DPRINT("Leave NtGdiSaveDC: %ld\n", lSaveDepth);
DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave);
return lSaveDepth;
}

View File

@@ -145,7 +145,7 @@ IntSetDefaultRegion(PDC pdc)
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;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -64,14 +64,14 @@ typedef struct _Rect
} 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;
@@ -332,7 +332,7 @@ app_draw_ellipse(DC *g, Rect r, PBRUSH pbrush)
*
* 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
@@ -376,7 +376,7 @@ app_fill_arc_rect(DC *g,
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 */
@@ -599,7 +599,7 @@ app_fill_arc_rect(DC *g,
* 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
@@ -912,7 +912,7 @@ app_fill_arc(DC *g, Rect r, int start_angle, int end_angle, PBRUSH pbrush, BOOL
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;
@@ -1273,7 +1273,7 @@ IntFillArc( PDC dc,
pdcattr = dc->pdcattr;
pbrush = BRUSH_LockBrush(pdcattr->hbrush);
if (!pbrush)
if (!pbrush)
{
DPRINT1("FillArc Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
@@ -1285,7 +1285,7 @@ IntFillArc( PDC dc,
(dc->dclevel.flPath & DCPATH_CLOCKWISE) ? -Start : -End,
pbrush, Chord);
BRUSH_UnlockBrush(pbrush);
BRUSH_UnlockBrush(pbrush);
return ret;
}
@@ -1329,7 +1329,7 @@ IntFillEllipse( PDC dc,
INT XLeft,
INT YLeft,
INT Width,
INT Height,
INT Height,
PBRUSH pbrush)
{
return (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), pbrush);
@@ -1343,7 +1343,7 @@ IntFillRoundRect( PDC dc,
INT Right,
INT Bottom,
INT Wellipse,
INT Hellipse,
INT Hellipse,
PBRUSH pbrush)
{
Rect r;
@@ -1385,7 +1385,7 @@ IntFillRoundRect( PDC dc,
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)
{
@@ -1419,7 +1419,7 @@ IntDrawRoundRect( PDC dc,
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
@@ -1437,7 +1437,7 @@ IntDrawRoundRect( PDC dc,
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
{

View File

@@ -110,7 +110,7 @@ IntGdiPolygon(PDC dc,
psurf,
&dc->eboFill.BrushObject,
Points,
Count,
Count,
DestRect,
&BrushOrigin);
}
@@ -271,15 +271,15 @@ NtGdiEllipse(
}
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;
@@ -298,7 +298,7 @@ NtGdiEllipse(
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);
@@ -478,6 +478,15 @@ NtGdiPolyPolyDraw( IN HDC hDC,
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)
{
@@ -502,6 +511,7 @@ NtGdiPolyPolyDraw( IN HDC hDC,
}
/* Cleanup and return */
DC_vFinishBlit(dc, NULL);
DC_UnlockDc(dc);
ExFreePool(pTemp);
@@ -529,19 +539,6 @@ IntRectangle(PDC dc,
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) )
{
@@ -567,6 +564,8 @@ IntRectangle(PDC dc,
DestRect.bottom--;
}
DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
DC_vUpdateFillBrush(dc);
@@ -580,6 +579,7 @@ IntRectangle(PDC dc,
ret = FALSE;
goto cleanup;
}
psurf = dc->dclevel.pSurface;
if (!psurf)
{
@@ -645,6 +645,8 @@ IntRectangle(PDC dc,
}
cleanup:
DC_vFinishBlit(dc, NULL);
/* Move current position in DC?
MSDN: The current position is neither used nor updated by Rectangle. */
@@ -675,8 +677,25 @@ NtGdiRectangle(HDC hDC,
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;
}
@@ -750,7 +769,7 @@ IntRoundRect(
}
if (!PenWidth) PenWidth = 1;
pbrushLine->ptPenWidth.x = PenWidth;
pbrushLine->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.top = Top;
@@ -765,12 +784,12 @@ IntRoundRect(
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));
@@ -849,16 +868,14 @@ GreGradientFill(
{
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;
@@ -888,13 +905,13 @@ GreGradientFill(
/* 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 */
@@ -902,11 +919,11 @@ GreGradientFill(
}
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 */
@@ -919,8 +936,8 @@ GreGradientFill(
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;
@@ -928,33 +945,29 @@ GreGradientFill(
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;
@@ -996,16 +1009,16 @@ NtGdiGradientFill(
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;
@@ -1048,8 +1061,6 @@ NtGdiExtFloodFill(
PDC dc;
PDC_ATTR pdcattr;
SURFACE *psurf = NULL;
HPALETTE hpal;
PPALETTE ppal;
EXLATEOBJ exlo;
BOOL Ret = FALSE;
RECTL DestRect;
@@ -1094,11 +1105,7 @@ NtGdiExtFloodFill(
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):
@@ -1108,7 +1115,6 @@ NtGdiExtFloodFill(
Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
EXLATEOBJ_vCleanup(&exlo);
PALETTE_ShareUnlockPalette(ppal);
cleanup:
DC_UnlockDc(dc);

View File

@@ -2249,7 +2249,7 @@ TextIntGetTextExtentPoint(PDC 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;
}
@@ -3160,7 +3160,7 @@ GreExtTextOutW(
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;
@@ -3175,8 +3175,6 @@ GreExtTextOutW(
BOOLEAN Render;
POINT Start;
BOOL DoBreak = FALSE;
HPALETTE hDestPalette;
PPALETTE ppalDst;
USHORT DxShift;
// TODO: Write test-cases to exactly match real Windows in different
@@ -3196,9 +3194,6 @@ GreExtTextOutW(
pdcattr = dc->pdcattr;
if (pdcattr->ulDirty_ & DIRTY_TEXT)
DC_vUpdateTextBrush(dc);
if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE)
{
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
@@ -3232,13 +3227,6 @@ GreExtTextOutW(
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);
@@ -3267,8 +3255,13 @@ GreExtTextOutW(
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,
@@ -3280,6 +3273,7 @@ GreExtTextOutW(
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
fuOptions &= ~ETO_OPAQUE;
DC_vFinishBlit(dc, NULL);
}
else
{
@@ -3444,19 +3438,24 @@ GreExtTextOutW(
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)
@@ -3505,6 +3504,7 @@ GreExtTextOutW(
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,
@@ -3517,7 +3517,9 @@ GreExtTextOutW(
&dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
MouseSafetyOnDrawEnd(dc->ppdev);
BackgroundLeft = DestRect.right;
}
DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left;
@@ -3570,7 +3572,7 @@ GreExtTextOutW(
DestRect.right = lprc->right + dc->ptlDCOrig.x;
DoBreak = TRUE;
}
MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
IntEngMaskBlt(
SurfObj,
SourceGlyphSurf,
@@ -3581,6 +3583,7 @@ GreExtTextOutW(
(PPOINTL)&MaskRect,
&dc->eboText.BrushObject,
&BrushOrigin);
MouseSafetyOnDrawEnd(dc->ppdev) ;
EngUnlockSurface(SourceGlyphSurf);
EngDeleteSurface((HSURF)HSourceGlyph);
@@ -3610,9 +3613,9 @@ GreExtTextOutW(
String++;
}
IntUnLockFreeType;
DC_vFinishBlit(dc, NULL) ;
EXLATEOBJ_vCleanup(&exloRGB2Dst);
EXLATEOBJ_vCleanup(&exloDst2RGB);
if (TextObj != NULL)
@@ -3628,6 +3631,7 @@ fail2:
fail:
if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj);
DC_UnlockDc(dc);
return FALSE;

View File

@@ -51,8 +51,9 @@ SynchonizeDriver(FLONG Flags)
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);

View File

@@ -8,7 +8,7 @@
/** INCLUDES ******************************************************************/
//#define GDI_DEBUG
#define GDI_DEBUG
#include <win32k.h>
#define NDEBUG
@@ -635,10 +635,7 @@ LockHandle:
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))
{
@@ -649,7 +646,7 @@ LockHandle:
}
ObDereferenceObject(OldProcess);
}
(void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
(void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, NULL);
/* Don't wait on shared locks */
return FALSE;
}
@@ -660,7 +657,7 @@ LockHandle:
*/
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 */
@@ -702,7 +699,7 @@ LockHandle:
}
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);
}
}
@@ -833,7 +830,7 @@ GreDeleteObject(HGDIOBJ hObject)
break;
case GDI_OBJECT_TYPE_DC:
DC_FreeDcAttr(hObject);
// DC_FreeDcAttr(hObject);
break;
}
@@ -970,12 +967,14 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
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];
@@ -1001,7 +1000,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
{
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;
}
@@ -1077,6 +1076,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType)
/*
* The handle is currently locked, wait some time and try again.
*/
GDIDBG_TRACELOOP(hObj, PrevProcId, NULL);
DelayExecution();
continue;
@@ -1649,6 +1649,38 @@ GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process)
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
@@ -1741,10 +1773,9 @@ IntGdiSetDCOwnerEx( HDC hDC, DWORD OwnerMask, BOOL NoSetBrush)
{
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;
}

View File

@@ -256,9 +256,9 @@ UpdateDeviceGammaRamp( HDEV hPDev )
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
{

View File

@@ -113,9 +113,6 @@ IntGdiLineTo(DC *dc,
}
else
{
if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
DC_vUpdateLineBrush(dc);
psurf = dc->dclevel.pSurface;
if (NULL == psurf)
{
@@ -250,6 +247,9 @@ IntGdiPolyline(DC *dc,
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);
@@ -295,6 +295,8 @@ IntGdiPolyline(DC *dc,
}
}
DC_vFinishBlit(dc, NULL);
return Ret;
}
@@ -376,6 +378,7 @@ NtGdiLineTo(HDC hDC,
{
DC *dc;
BOOL Ret;
RECT rcLockRect ;
dc = DC_LockDc(hDC);
if (!dc)
@@ -390,8 +393,28 @@ NtGdiLineTo(HDC hDC,
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;
}

View File

@@ -14,7 +14,8 @@
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] =
{
@@ -84,18 +85,51 @@ HPALETTE FASTCALL PALETTE_Init(VOID)
/* 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;
}
@@ -128,7 +162,7 @@ PALETTE_AllocPalette(ULONG Mode,
NewPalette = PalGDI->BaseObject.hHmgr;
PalGDI->Self = NewPalette;
PalGDI->Mode = Mode;
PalGDI->flFlags = Mode;
if (NULL != Colors)
{
@@ -144,20 +178,22 @@ PALETTE_AllocPalette(ULONG Mode,
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);
@@ -183,7 +219,7 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors,
NewPalette = PalGDI->BaseObject.hHmgr;
PalGDI->Self = NewPalette;
PalGDI->Mode = PAL_INDEXED;
PalGDI->flFlags = PAL_INDEXED;
PalGDI->IndexedColors = ExAllocatePoolWithTag(PagedPool,
sizeof(PALETTEENTRY) * NumColors,
@@ -287,7 +323,7 @@ ULONG
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);
@@ -299,19 +335,19 @@ PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors)
{
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;
@@ -358,7 +394,7 @@ EngCreatePalette(
{
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);
@@ -399,7 +435,7 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG *PaletteEntry
/* 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;
@@ -630,17 +666,17 @@ COLORREF APIENTRY NtGdiGetNearestColor(HDC hDC, COLORREF Color)
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);
@@ -668,7 +704,7 @@ NtGdiGetNearestPaletteIndex(
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);

View File

@@ -408,7 +408,7 @@ BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_wid
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)
@@ -544,7 +544,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2,
if ( pPath->state != PATH_Open )
{
Ret = FALSE;
goto ArcExit;
goto ArcExit;
}
/* Check for zero height / width */
@@ -697,7 +697,7 @@ PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints )
pPath = PATH_LockPath( dc->dclevel.hPath );
if (!pPath) return FALSE;
/* Check that path is open */
if ( pPath->state != PATH_Open )
{
@@ -805,7 +805,7 @@ PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints )
pPath = PATH_LockPath( dc->dclevel.hPath );
if (!pPath) return FALSE;
/* Check that path is open */
if ( pPath->state != PATH_Open )
{
@@ -1597,7 +1597,7 @@ PATH_WidenPath(DC *dc)
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.
@@ -1627,7 +1627,7 @@ PATH_WidenPath(DC *dc)
}
}
pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
PATH_InitGdiPath(pNewPath);
pNewPath->state = PATH_Open;
@@ -2012,7 +2012,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
}
IntGdiCloseFigure( pPath );
PATH_UnlockPath( pPath );
PATH_UnlockPath( pPath );
return TRUE;
}
@@ -2020,7 +2020,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
* 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)
{
@@ -2210,7 +2210,7 @@ NtGdiCloseFigure(HDC hDC)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
pPath = PATH_LockPath( pDc->dclevel.hPath );
if (!pPath)
{
@@ -2281,7 +2281,7 @@ NtGdiFillPath(HDC hDC)
PPATH pPath;
PDC_ATTR pdcattr;
PDC dc = DC_LockDc ( hDC );
if ( !dc )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
@@ -2294,6 +2294,9 @@ NtGdiFillPath(HDC hDC)
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))
@@ -2311,6 +2314,7 @@ NtGdiFillPath(HDC hDC)
}
PATH_UnlockPath( pPath );
DC_vFinishBlit(dc, NULL);
DC_UnlockDc ( dc );
return ret;
}
@@ -2328,7 +2332,7 @@ NtGdiFlattenPath(HDC hDC)
pDc = DC_LockDc(hDC);
if (!pDc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
@@ -2572,6 +2576,9 @@ NtGdiStrokeAndFillPath(HDC hDC)
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))
@@ -2585,6 +2592,7 @@ NtGdiStrokeAndFillPath(HDC hDC)
if (bRet) PATH_EmptyPath(pPath);
PATH_UnlockPath( pPath );
DC_vFinishBlit(pDc, NULL);
DC_UnlockDc(pDc);
return bRet;
}
@@ -2612,12 +2620,17 @@ NtGdiStrokePath(HDC hDC)
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 );
@@ -2630,7 +2643,7 @@ APIENTRY
NtGdiWidenPath(HDC hDC)
{
BOOL Ret;
PDC pdc = DC_LockDc ( hDC );
PDC pdc = DC_LockDc ( hDC );
if ( !pdc )
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);

View File

@@ -63,11 +63,11 @@ IntGdiExtCreatePen(
{
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);
@@ -125,27 +125,27 @@ IntGdiExtCreatePen(
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:

View File

@@ -3687,7 +3687,7 @@ NtGdiGetRandomRgn(
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;

Some files were not shown because too many files have changed in this diff Show More