📄 windc.c
字号:
{
DceUpdateVisRgn(Dce, Window, Flags);
}
return(Dce->hDC);
}
HDC STDCALL
NtUserGetDCEx(HWND hWnd OPTIONAL, HANDLE ClipRegion, ULONG Flags)
{
PWINDOW_OBJECT Wnd=NULL;
DECLARE_RETURN(HDC);
DPRINT("Enter NtUserGetDCEx\n");
UserEnterExclusive();
if (hWnd && !(Wnd = UserGetWindowObject(hWnd)))
{
RETURN(NULL);
}
RETURN( UserGetDCEx(Wnd, ClipRegion, Flags));
CLEANUP:
DPRINT("Leave NtUserGetDCEx, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
BOOL FASTCALL
DCE_Cleanup(PDCE pDce)
{
PDCE PrevInList;
KeEnterCriticalRegion();
if (pDce == FirstDce)
{
FirstDce = pDce->next;
PrevInList = pDce;
}
else
{
for (PrevInList = FirstDce; NULL != PrevInList; PrevInList = PrevInList->next)
{
if (pDce == PrevInList->next)
{
PrevInList->next = pDce->next;
break;
}
}
assert(NULL != PrevInList);
}
KeLeaveCriticalRegion();
return NULL != PrevInList;
}
HWND FASTCALL
IntWindowFromDC(HDC hDc)
{
DCE *Dce;
KeEnterCriticalRegion();
for (Dce = FirstDce; Dce != NULL; Dce = Dce->next)
{
if(Dce->hDC == hDc)
{
KeLeaveCriticalRegion();
return Dce->hwndCurrent;
}
}
KeLeaveCriticalRegion();
return 0;
}
INT FASTCALL
UserReleaseDC(PWINDOW_OBJECT Window, HDC hDc, BOOL EndPaint)
{
DCE *dce;
INT nRet = 0;
dce = FirstDce;
DPRINT("%p %p\n", Window, hDc);
KeEnterCriticalRegion();
while (dce && (dce->hDC != hDc))
{
dce = dce->next;
}
KeLeaveCriticalRegion();
if (dce && (dce->DCXFlags & DCX_DCEBUSY))
{
nRet = DceReleaseDC(dce, EndPaint);
}
return nRet;
}
// Win 3.1 throw back, hWnd should be ignored and not used.
// Replace with NtUserCallOneParam ((DWORD) hDC, ONEPARAM_ROUTINE_RELEASEDC);
INT STDCALL
NtUserReleaseDC(HWND hWnd, HDC hDc)
{
DECLARE_RETURN(INT);
DPRINT("Enter NtUserReleaseDC\n");
UserEnterExclusive();
RETURN(UserReleaseDC(NULL, hDc, FALSE));
CLEANUP:
DPRINT("Leave NtUserReleaseDC, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/***********************************************************************
* DceFreeDCE
*/
PDCE FASTCALL
DceFreeDCE(PDCE pdce, BOOLEAN Force)
{
DCE *ret;
if (NULL == pdce)
{
return NULL;
}
ret = pdce->next;
#if 0 /* FIXME */
SetDCHook(pdce->hDC, NULL, 0L);
#endif
if(Force && !GDIOBJ_OwnedByCurrentProcess(GdiHandleTable, pdce->hDC))
{
DC_SetOwnership( pdce->hDC, PsGetCurrentProcess());
}
NtGdiDeleteObjectApp(pdce->hDC);
if (pdce->hClipRgn && ! (pdce->DCXFlags & DCX_KEEPCLIPRGN))
{
NtGdiDeleteObject(pdce->hClipRgn);
}
DCE_Cleanup(pdce);
ExFreePoolWithTag(pdce, TAG_PDCE);
return ret;
}
/***********************************************************************
* DceFreeWindowDCE
*
* Remove owned DCE and reset unreleased cache DCEs.
*/
void FASTCALL
DceFreeWindowDCE(PWINDOW_OBJECT Window)
{
DCE *pDCE;
pDCE = FirstDce;
KeEnterCriticalRegion();
while (pDCE)
{
if (pDCE->hwndCurrent == Window->hSelf)
{
if (pDCE == Window->Dce) /* owned or Class DCE*/
{
if (Window->Class->Style & CS_OWNDC) /* owned DCE*/
{
pDCE = DceFreeDCE(pDCE, FALSE);
Window->Dce = NULL;
continue;
}
else if (pDCE->DCXFlags & (DCX_INTERSECTRGN | DCX_EXCLUDERGN)) /* Class DCE*/
{
DceDeleteClipRgn(pDCE);
pDCE->hwndCurrent = 0;
}
}
else
{
if (pDCE->DCXFlags & DCX_DCEBUSY) /* shared cache DCE */
{
/* FIXME: AFAICS we are doing the right thing here so
* this should be a DPRINT. But this is best left as an ERR
* because the 'application error' is likely to come from
* another part of Wine (i.e. it's our fault after all).
* We should change this to DPRINT when ReactOS is more stable
* (for 1.0?).
*/
DPRINT1("[%p] GetDC() without ReleaseDC()!\n", Window->hSelf);
DceReleaseDC(pDCE, FALSE);
}
pDCE->DCXFlags &= DCX_CACHE;
pDCE->DCXFlags |= DCX_DCEEMPTY;
pDCE->hwndCurrent = 0;
}
}
pDCE = pDCE->next;
}
KeLeaveCriticalRegion();
}
VOID FASTCALL
DceEmptyCache()
{
KeEnterCriticalRegion();
while (FirstDce != NULL)
{
FirstDce = DceFreeDCE(FirstDce, TRUE);
}
KeLeaveCriticalRegion();
}
VOID FASTCALL
DceResetActiveDCEs(PWINDOW_OBJECT Window)
{
DCE *pDCE;
PDC dc;
PWINDOW_OBJECT CurrentWindow;
INT DeltaX;
INT DeltaY;
if (NULL == Window)
{
return;
}
pDCE = FirstDce;
while (pDCE)
{
if (0 == (pDCE->DCXFlags & DCX_DCEEMPTY))
{
if (Window->hSelf == pDCE->hwndCurrent)
{
CurrentWindow = Window;
}
else
{
CurrentWindow = UserGetWindowObject(pDCE->hwndCurrent);
if (NULL == CurrentWindow)
{
pDCE = pDCE->next;
continue;
}
}
dc = DC_LockDc(pDCE->hDC);
if (dc == NULL)
{
// if (Window->hSelf != pDCE->hwndCurrent)
// {
// UserDerefObject(CurrentWindow);
// }
pDCE = pDCE->next;
continue;
}
if (Window == CurrentWindow || IntIsChildWindow(Window, CurrentWindow))
{
if (pDCE->DCXFlags & DCX_WINDOW)
{
DeltaX = CurrentWindow->WindowRect.left - dc->w.DCOrgX;
DeltaY = CurrentWindow->WindowRect.top - dc->w.DCOrgY;
dc->w.DCOrgX = CurrentWindow->WindowRect.left;
dc->w.DCOrgY = CurrentWindow->WindowRect.top;
}
else
{
DeltaX = CurrentWindow->ClientRect.left - dc->w.DCOrgX;
DeltaY = CurrentWindow->ClientRect.top - dc->w.DCOrgY;
dc->w.DCOrgX = CurrentWindow->ClientRect.left;
dc->w.DCOrgY = CurrentWindow->ClientRect.top;
}
if (NULL != dc->w.hClipRgn)
{
int FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
NtGdiOffsetRgn(dc->w.hClipRgn, DeltaX, DeltaY);
CLIPPING_UpdateGCRegion(dc);
}
if (NULL != pDCE->hClipRgn)
{
NtGdiOffsetRgn(pDCE->hClipRgn, DeltaX, DeltaY);
}
}
DC_UnlockDc(dc);
DceUpdateVisRgn(pDCE, CurrentWindow, pDCE->DCXFlags);
if (Window->hSelf != pDCE->hwndCurrent)
{
// IntEngWindowChanged(CurrentWindow, WOC_RGN_CLIENT);
// UserDerefObject(CurrentWindow);
}
}
pDCE = pDCE->next;
}
}
#define COPY_DEVMODE_VALUE_TO_CALLER(dst, src, member) \
Status = MmCopyToCaller(&(dst)->member, &(src)->member, sizeof ((src)->member)); \
if (!NT_SUCCESS(Status)) \
{ \
SetLastNtError(Status); \
ExFreePool(src); \
return FALSE; \
}
BOOL
STDCALL
NtUserEnumDisplaySettings(
PUNICODE_STRING lpszDeviceName,
DWORD iModeNum,
LPDEVMODEW lpDevMode, /* FIXME is this correct? */
DWORD dwFlags )
{
NTSTATUS Status;
LPDEVMODEW pSafeDevMode;
PUNICODE_STRING pSafeDeviceName = NULL;
UNICODE_STRING SafeDeviceName;
USHORT Size = 0, ExtraSize = 0;
/* Copy the devmode */
Status = MmCopyFromCaller(&Size, &lpDevMode->dmSize, sizeof (Size));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
Status = MmCopyFromCaller(&ExtraSize, &lpDevMode->dmDriverExtra, sizeof (ExtraSize));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
pSafeDevMode = ExAllocatePool(PagedPool, Size + ExtraSize);
if (pSafeDevMode == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
pSafeDevMode->dmSize = Size;
pSafeDevMode->dmDriverExtra = ExtraSize;
/* Copy the device name */
if (lpszDeviceName != NULL)
{
Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
if (!NT_SUCCESS(Status))
{
ExFreePool(pSafeDevMode);
SetLastNtError(Status);
return FALSE;
}
pSafeDeviceName = &SafeDeviceName;
}
/* Call internal function */
if (!IntEnumDisplaySettings(pSafeDeviceName, iModeNum, pSafeDevMode, dwFlags))
{
if (pSafeDeviceName != NULL)
RtlFreeUnicodeString(pSafeDeviceName);
ExFreePool(pSafeDevMode);
return FALSE;
}
if (pSafeDeviceName != NULL)
RtlFreeUnicodeString(pSafeDeviceName);
/* Copy some information back */
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsWidth);
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmPelsHeight);
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmBitsPerPel);
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmDisplayFrequency);
COPY_DEVMODE_VALUE_TO_CALLER(lpDevMode, pSafeDevMode, dmDisplayFlags);
/* output private/extra driver data */
if (ExtraSize > 0)
{
Status = MmCopyToCaller((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
ExFreePool(pSafeDevMode);
return FALSE;
}
}
ExFreePool(pSafeDevMode);
return TRUE;
}
#undef COPY_DEVMODE_VALUE_TO_CALLER
LONG
STDCALL
NtUserChangeDisplaySettings(
PUNICODE_STRING lpszDeviceName,
LPDEVMODEW lpDevMode,
HWND hwnd,
DWORD dwflags,
LPVOID lParam)
{
NTSTATUS Status;
DEVMODEW DevMode;
PUNICODE_STRING pSafeDeviceName = NULL;
UNICODE_STRING SafeDeviceName;
LONG Ret;
/* Check arguments */
#ifdef CDS_VIDEOPARAMETERS
if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL)
#else
if (lParam != NULL)
#endif
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return DISP_CHANGE_BADPARAM;
}
if (hwnd != NULL)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return DISP_CHANGE_BADPARAM;
}
/* Copy devmode */
Status = MmCopyFromCaller(&DevMode.dmSize, &lpDevMode->dmSize, sizeof (DevMode.dmSize));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return DISP_CHANGE_BADPARAM;
}
DevMode.dmSize = min(sizeof (DevMode), DevMode.dmSize);
Status = MmCopyFromCaller(&DevMode, lpDevMode, DevMode.dmSize);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return DISP_CHANGE_BADPARAM;
}
if (DevMode.dmDriverExtra > 0)
{
DbgPrint("(%s:%i) WIN32K: %s lpDevMode->dmDriverExtra is IGNORED!\n", __FILE__, __LINE__, __FUNCTION__);
DevMode.dmDriverExtra = 0;
}
/* Copy the device name */
if (lpszDeviceName != NULL)
{
Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return DISP_CHANGE_BADPARAM;
}
pSafeDeviceName = &SafeDeviceName;
}
/* Call internal function */
Ret = IntChangeDisplaySettings(pSafeDeviceName, &DevMode, dwflags, lParam);
if (pSafeDeviceName != NULL)
RtlFreeUnicodeString(pSafeDeviceName);
return Ret;
}
/*!
* Select logical palette into device context.
* \param hDC handle to the device context
* \param hpal handle to the palette
* \param ForceBackground If this value is FALSE the logical palette will be copied to the device palette only when the applicatioon
* is in the foreground. If this value is TRUE then map the colors in the logical palette to the device
* palette colors in the best way.
* \return old palette
*
* \todo implement ForceBackground == TRUE
*/
HPALETTE STDCALL NtUserSelectPalette(HDC hDC,
HPALETTE hpal,
BOOL ForceBackground)
{
PDC dc;
HPALETTE oldPal = NULL;
PPALGDI PalGDI;
// FIXME: mark the palette as a [fore\back]ground pal
dc = DC_LockDc(hDC);
if (NULL != dc)
{
/* Check if this is a valid palette handle */
PalGDI = PALETTE_LockPalette(hpal);
if (NULL != PalGDI)
{
/* Is this a valid palette for this depth? */
if ((dc->w.bitsPerPixel <= 8 && PAL_INDEXED == PalGDI->Mode)
|| (8 < dc->w.bitsPerPixel && PAL_INDEXED != PalGDI->Mode))
{
PALETTE_UnlockPalette(PalGDI);
oldPal = dc->w.hPalette;
dc->w.hPalette = hpal;
}
else if (8 < dc->w.bitsPerPixel && PAL_INDEXED == PalGDI->Mode)
{
PALETTE_UnlockPalette(PalGDI);
oldPal = dc->PalIndexed;
dc->PalIndexed = hpal;
}
else
{
PALETTE_UnlockPalette(PalGDI);
oldPal = NULL;
}
}
else
{
oldPal = NULL;
}
DC_UnlockDc(dc);
}
return oldPal;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -