mirror of
https://github.com/reactos/reactos
synced 2025-10-06 08:22:58 +02:00
[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:
@@ -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);
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 );
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
123
reactos/subsystems/win32/win32k/dib/alphablend.c
Normal file
123
reactos/subsystems/win32/win32k/dib/alphablend.c
Normal 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;
|
||||
}
|
||||
|
@@ -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 */
|
||||
{
|
||||
|
@@ -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];
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
504
reactos/subsystems/win32/win32k/eng/ldevobj.c
Normal file
504
reactos/subsystems/win32/win32k/eng/ldevobj.c
Normal 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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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 );
|
||||
|
844
reactos/subsystems/win32/win32k/eng/pdevobj.c
Normal file
844
reactos/subsystems/win32/win32k/eng/pdevobj.c
Normal 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;
|
||||
}
|
99
reactos/subsystems/win32/win32k/eng/rlecomp.c
Normal file
99
reactos/subsystems/win32/win32k/eng/rlecomp.c
Normal 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;
|
||||
}
|
@@ -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
|
||||
*/
|
||||
|
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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++)
|
||||
|
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
57
reactos/subsystems/win32/win32k/include/device.h
Normal file
57
reactos/subsystems/win32/win32k/include/device.h
Normal 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;
|
@@ -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);
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
86
reactos/subsystems/win32/win32k/include/ldevobj.h
Normal file
86
reactos/subsystems/win32/win32k/include/ldevobj.h
Normal 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);
|
||||
|
@@ -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(
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
@@ -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 */
|
||||
|
@@ -14,7 +14,7 @@ typedef struct _ROSRGNDATA
|
||||
|
||||
RGNDATAHEADER rdh;
|
||||
RECTL *Buffer;
|
||||
} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA;
|
||||
} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA, REGION, *PREGION;
|
||||
|
||||
|
||||
/* Functions ******************************************************************/
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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 */
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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");
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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
@@ -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)
|
||||
{
|
||||
|
@@ -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();
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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(
|
||||
|
@@ -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)
|
||||
|
@@ -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!
|
||||
//
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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
@@ -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
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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:
|
||||
|
@@ -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
Reference in New Issue
Block a user