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

📄 dc.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
       }
       NtGdiDeleteObjectApp (hdcs);
  }
  DC_UnlockDc( dc );
  return  success;
}
  

INT STDCALL
NtGdiSaveDC(HDC  hDC)
{
  HDC  hdcs;
  PDC  dc, dcs;
  INT  ret;

  DPRINT("NtGdiSaveDC(%lx)\n", hDC);

  if (!(hdcs = NtGdiGetDCState(hDC)))
  {
    return 0;
  }

  dcs = DC_LockDc (hdcs);
  if (dcs == NULL)
  {
    SetLastWin32Error(ERROR_INVALID_HANDLE);
    return 0;
  }
  dc = DC_LockDc (hDC);
  if (dc == NULL)
  {
    DC_UnlockDc(dcs);
    SetLastWin32Error(ERROR_INVALID_HANDLE);
    return 0;
  }

#if 0
    /* Copy path. The reason why path saving / restoring is in SaveDC/
     * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
     * functions are only in Win16 (which doesn't have paths) and that
     * SetDCState doesn't allow us to signal an error (which can happen
     * when copying paths).
     */
  if (!PATH_AssignGdiPath (&dcs->w.path, &dc->w.path))
  {
    NtGdiDeleteObjectApp (hdcs);
    return 0;
  }
#endif

  DC_SetNextDC (dcs, DC_GetNextDC (dc));
  DC_SetNextDC (dc, hdcs);
  ret = ++dc->saveLevel;
  DC_UnlockDc( dcs );
  DC_UnlockDc( dc );

  return  ret;
}

HGDIOBJ
STDCALL
NtGdiSelectObject(HDC  hDC, HGDIOBJ  hGDIObj)
{
  HGDIOBJ objOrg = NULL; // default to failure
  BITMAPOBJ *pb;
  PDC dc;
  PGDIBRUSHOBJ pen;
  PGDIBRUSHOBJ brush;
  XLATEOBJ *XlateObj;
  DWORD objectType;
  HRGN hVisRgn;
  BOOLEAN Failed;

  if (!hDC || !hGDIObj)
    {
    /* From Wine:
     * SelectObject() with a NULL DC returns 0 and sets ERROR_INVALID_HANDLE.
     * Note: Under XP at least invalid ptrs can also be passed, not just NULL;
     *       Don't test that here in case it crashes earlier win versions.
     */
       if (!hDC) SetLastWin32Error(ERROR_INVALID_HANDLE);
       return NULL;
    }

  dc = DC_LockDc(hDC);
  if (NULL == dc)
    {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return NULL;
    }

  objectType = GDIOBJ_GetObjectType(hGDIObj);

  switch (objectType)
  {
    case GDI_OBJECT_TYPE_PEN:
      pen = PENOBJ_LockPen((HPEN) hGDIObj);
      if (pen == NULL)
      {
        SetLastWin32Error(ERROR_INVALID_HANDLE);
        break;
      }

      XlateObj = IntGdiCreateBrushXlate(dc, pen, &Failed);
      PENOBJ_UnlockPen(pen);
      if (Failed)
      {
        SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
        break;
      }

      objOrg = (HGDIOBJ)dc->w.hPen;
      dc->w.hPen = hGDIObj;
      if (dc->XlatePen != NULL)
        EngDeleteXlate(dc->XlatePen);
      dc->XlatePen = XlateObj;
      break;

    case GDI_OBJECT_TYPE_BRUSH:
      brush = BRUSHOBJ_LockBrush((HPEN) hGDIObj);
      if (brush == NULL)
      {
        SetLastWin32Error(ERROR_INVALID_HANDLE);
        break;
      }

      XlateObj = IntGdiCreateBrushXlate(dc, brush, &Failed);
      BRUSHOBJ_UnlockBrush(brush);
      if (Failed)
      {
        SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
        break;
      }

      objOrg = (HGDIOBJ)dc->w.hBrush;
      dc->w.hBrush = hGDIObj;
      if (dc->XlateBrush != NULL)
        EngDeleteXlate(dc->XlateBrush);
      dc->XlateBrush = XlateObj;
      break;

    case GDI_OBJECT_TYPE_FONT:
      if(NT_SUCCESS(TextIntRealizeFont((HFONT)hGDIObj)))
      {
        objOrg = (HGDIOBJ)dc->w.hFont;
        dc->w.hFont = (HFONT) hGDIObj;
      }
      break;

    case GDI_OBJECT_TYPE_BITMAP:
      // must be memory dc to select bitmap
      if (!(dc->w.flags & DC_MEMORY))
        {
          DC_UnlockDc(dc);
          return NULL;
        }
      pb = BITMAPOBJ_LockBitmap(hGDIObj);
      if (NULL == pb)
        {
          SetLastWin32Error(ERROR_INVALID_HANDLE);
          DC_UnlockDc(dc);
          return NULL;
        }
      objOrg = (HGDIOBJ)dc->w.hBitmap;

      /* Release the old bitmap, lock the new one and convert it to a SURF */
      dc->w.hBitmap = hGDIObj;

      // if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
      if(pb->dib)
      {
        dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount;
        dc->w.hPalette = pb->hDIBPalette;
      }
      else
      {
        dc->w.bitsPerPixel = BitsPerFormat(pb->SurfObj.iBitmapFormat);
        dc->w.hPalette = dc->DevInfo->hpalDefault;
      }

      /* Reselect brush and pen to regenerate the XLATEOBJs. */
      NtGdiSelectObject ( hDC, dc->w.hBrush );
      NtGdiSelectObject ( hDC, dc->w.hPen );

      DC_UnlockDc ( dc );
      hVisRgn = NtGdiCreateRectRgn ( 0, 0, pb->SurfObj.sizlBitmap.cx, pb->SurfObj.sizlBitmap.cy );
      BITMAPOBJ_UnlockBitmap( pb );
      NtGdiSelectVisRgn ( hDC, hVisRgn );
      NtGdiDeleteObject ( hVisRgn );

      return objOrg;

    case GDI_OBJECT_TYPE_REGION:
      DC_UnlockDc (dc);
      /*
       * The return value is one of the following values:
       *  SIMPLEREGION
       *  COMPLEXREGION
       *  NULLREGION
       */
      return (HGDIOBJ) NtGdiSelectClipRgn(hDC, (HRGN) hGDIObj);

    default:
      break;
  }
  DC_UnlockDc( dc );
  return objOrg;
}

WORD STDCALL
NtGdiSetHookFlags(HDC hDC, WORD Flags)
{
  WORD wRet;
  DC *dc = DC_LockDc(hDC);

  if (NULL == dc)
    {
      SetLastWin32Error(ERROR_INVALID_HANDLE);
      return 0;
    }

  wRet = dc->w.flags & DC_DIRTY;

  /* "Undocumented Windows" info is slightly confusing.
   */

  DPRINT("DC %p, Flags %04x\n", hDC, Flags);

  if (Flags & DCHF_INVALIDATEVISRGN)
    {
      dc->w.flags |= DC_DIRTY;
    }
  else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
    {
      dc->w.flags &= ~DC_DIRTY;
    }

  DC_UnlockDc(dc);

  return wRet;
}

DC_SET_MODE( NtGdiSetBkMode, w.backgroundMode, TRANSPARENT, OPAQUE )
DC_SET_MODE( NtGdiSetPolyFillMode, w.polyFillMode, ALTERNATE, WINDING )
// DC_SET_MODE( NtGdiSetRelAbs, w.relAbsMode, ABSOLUTE, RELATIVE )
DC_SET_MODE( NtGdiSetROP2, w.ROPmode, R2_BLACK, R2_WHITE )
DC_SET_MODE( NtGdiSetStretchBltMode, w.stretchBltMode, BLACKONWHITE, HALFTONE )

//  ----------------------------------------------------  Private Interface

HDC FASTCALL
DC_AllocDC(PUNICODE_STRING Driver)
{
  PDC  NewDC;
  HDC  hDC;
  PWSTR Buf = NULL;

  if (Driver != NULL)
  {
    Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC);
    if(!Buf)
    {
      return NULL;
    }
    RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength);
  }

  hDC = (HDC) GDIOBJ_AllocObj(GdiHandleTable, GDI_OBJECT_TYPE_DC);
  if (hDC == NULL)
  {
    if(Buf)
    {
      ExFreePool(Buf);
    }
    return  NULL;
  }

  NewDC = DC_LockDc(hDC);
  /* FIXME - Handle NewDC == NULL! */

  if (Driver != NULL)
  {
    RtlCopyMemory(&NewDC->DriverName, Driver, sizeof(UNICODE_STRING));
    NewDC->DriverName.Buffer = Buf;
  }

  NewDC->w.xformWorld2Wnd.eM11 = 1.0f;
  NewDC->w.xformWorld2Wnd.eM12 = 0.0f;
  NewDC->w.xformWorld2Wnd.eM21 = 0.0f;
  NewDC->w.xformWorld2Wnd.eM22 = 1.0f;
  NewDC->w.xformWorld2Wnd.eDx = 0.0f;
  NewDC->w.xformWorld2Wnd.eDy = 0.0f;
  NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd;
  NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd;
  NewDC->w.vport2WorldValid = TRUE;
  NewDC->w.MapMode = MM_TEXT;
  NewDC->wndExtX = 1.0f;
  NewDC->wndExtY = 1.0f;
  NewDC->vportExtX = 1.0f;
  NewDC->vportExtY = 1.0f;
  NewDC->w.textColor = 0;
  NewDC->w.backgroundColor = 0xffffff;

  NewDC->w.hFont = NtGdiGetStockObject(SYSTEM_FONT);
  TextIntRealizeFont(NewDC->w.hFont);

  NewDC->w.hPalette = NtGdiGetStockObject(DEFAULT_PALETTE);

  DC_UnlockDc(NewDC);

  return  hDC;
}

HDC FASTCALL
DC_FindOpenDC(PUNICODE_STRING  Driver)
{
  return NULL;
}

/*!
 * Initialize some common fields in the Device Context structure.
*/
VOID FASTCALL
DC_InitDC(HDC  DCHandle)
{
//  NtGdiRealizeDefaultPalette(DCHandle);

  NtGdiSelectObject(DCHandle, NtGdiGetStockObject( WHITE_BRUSH ));
  NtGdiSelectObject(DCHandle, NtGdiGetStockObject( BLACK_PEN ));
  //NtGdiSelectObject(DCHandle, hFont);

/*
  {
    int res;
    res = CLIPPING_UpdateGCRegion(DCToInit);
    ASSERT ( res != ERROR );
  }
*/
}

VOID FASTCALL
DC_FreeDC(HDC  DCToFree)
{
  if (!GDIOBJ_FreeObj(GdiHandleTable, DCToFree, GDI_OBJECT_TYPE_DC))
  {
    DPRINT("DC_FreeDC failed\n");
  }
}

BOOL INTERNAL_CALL
DC_Cleanup(PVOID ObjectBody)
{
  PDC pDC = (PDC)ObjectBody;
  RtlFreeUnicodeString(&pDC->DriverName);
  return TRUE;
}

HDC FASTCALL
DC_GetNextDC (PDC pDC)
{
  return pDC->hNext;
}

VOID FASTCALL
DC_SetNextDC (PDC pDC, HDC hNextDC)
{
  pDC->hNext = hNextDC;
}

VOID FASTCALL
DC_UpdateXforms(PDC  dc)
{
  XFORM  xformWnd2Vport;
  FLOAT  scaleX, scaleY;

  /* Construct a transformation to do the window-to-viewport conversion */
  scaleX = (dc->wndExtX ? (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX : 0.0f);
  scaleY = (dc->wndExtY ? (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY : 0.0f);
  xformWnd2Vport.eM11 = scaleX;
  xformWnd2Vport.eM12 = 0.0;
  xformWnd2Vport.eM21 = 0.0;
  xformWnd2Vport.eM22 = scaleY;
  xformWnd2Vport.eDx  = (FLOAT)dc->vportOrgX - scaleX * (FLOAT)dc->wndOrgX;
  xformWnd2Vport.eDy  = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY;

  /* Combine with the world transformation */
  IntGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);

  /* Create inverse of world-to-viewport transformation */
  dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World);
}

BOOL FASTCALL
DC_InvertXform(const XFORM *xformSrc,
               XFORM *xformDest)
{
  FLOAT  determinant;

  determinant = xformSrc->eM11*xformSrc->eM22 - xformSrc->eM12*xformSrc->eM21;
  if (determinant > -1e-12 && determinant < 1e-12)
  {
    return  FALSE;
  }

  xformDest->eM11 =  xformSrc->eM22 / determinant;
  xformDest->eM12 = -xformSrc->eM12 / determinant;
  xformDest->eM21 = -xformSrc->eM21 / determinant;
  xformDest->eM22 =  xformSrc->eM11 / determinant;
  xformDest->eDx  = -xformSrc->eDx * xformDest->eM11 - xformSrc->eDy * xformDest->eM21;
  xformDest->eDy  = -xformSrc->eDx * xformDest->eM12 - xformSrc->eDy * xformDest->eM22;

  return  TRUE;
}

VOID FASTCALL
DC_SetOwnership(HDC hDC, PEPROCESS Owner)
{
  PDC DC;

  GDIOBJ_SetOwnership(GdiHandleTable, hDC, Owner);
  DC = DC_LockDc(hDC);
  if (NULL != DC)
    {
      if (NULL != DC->w.hClipRgn)
        {
          GDIOBJ_CopyOwnership(GdiHandleTable, hDC, DC->w.hClipRgn);
        }
      if (NULL != DC->w.hVisRgn)
        {
          GDIOBJ_CopyOwnership(GdiHandleTable, hDC, DC->w.hVisRgn);
        }
      if (NULL != DC->w.hGCClipRgn)
        {
          GDIOBJ_CopyOwnership(GdiHandleTable, hDC, DC->w.hGCClipRgn);
        }
      DC_UnlockDc(DC);
    }
}

BOOL FASTCALL
IntIsPrimarySurface(SURFOBJ *SurfObj)
{
   if (PrimarySurface.Handle == NULL)
     {
       return FALSE;
     }
   return SurfObj->hsurf == PrimarySurface.Handle;
}

/*
 * Returns the color of the brush or pen that is currently selected into the DC.
 * This function is called from GetDCBrushColor() and GetDCPenColor()
 */
COLORREF FASTCALL
IntGetDCColor(HDC hDC, ULONG Object)
{
   /*
    * The previous implementation was completly incorrect. It modified the
    * brush that was currently selected into the device context, but in fact
    * the DC pen/brush color should be stored directly in the device context
    * (at address 0x2C of the user mode DC object memory on Windows 2K/XP).
    * The actual color is then used when DC_BRUSH/DC_PEN object is selected
    * into the device context and BRUSHOBJ for drawing is composed (belongs
    * to IntGdiInitBrushInstance in the current ReactOS implementation). Also
    * the implementation should be moved to user mode GDI32.dll when UM
    * mapped GDI objects will be implemented.
    */

   DPRINT("WIN32K:IntGetDCColor is unimplemented\n");
   return 0xFFFFFF; /* The default DC color. */
}

/*
 * Changes the color of the brush or pen that is currently selected into the DC.
 * This function is called from SetDCBrushColor() and SetDCPenColor()
 */
COLORREF FASTCALL
IntSetDCColor(HDC hDC, ULONG Object, COLORREF Color)
{
   /* See the comment in IntGetDCColor. */

   DPRINT("WIN32K:IntSetDCColor is unimplemented\n");
   return CLR_INVALID;
}

#define SIZEOF_DEVMODEW_300 188
#define SIZEOF_DEVMODEW_400 212
#define SIZEOF_DEVMODEW_500 220

/*! \brief Enumerate possible display settings for the given display...
 *
 * \todo Make thread safe!?
 * \todo Don't ignore pDeviceName
 * \todo Implement non-raw mode (only return settings valid for driver and monitor)
 */
BOOL FASTCALL
IntEnumDisplaySettings(
  IN PUNICODE_STRING pDeviceName  OPTIONAL,
  IN DWORD iModeNum,
  IN OUT LPDEVMODEW pDevMode,
  IN DWORD dwFlags)
{
  static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL;
  static DWORD SizeOfCachedDevModes = 0;
  PDEVMOD

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -