⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windc.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
   {
      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 + -