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

📄 dc.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
        SetLastWin32Error(ERROR_INVALID_HANDLE);
        break;
      }

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

      objOrg = (HGDIOBJ)dc->Dc_Attr.hpen;
      dc->Dc_Attr.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->Dc_Attr.hbrush;
      dc->Dc_Attr.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->Dc_Attr.hlfntNew;
        dc->Dc_Attr.hlfntNew = (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->Dc_Attr.hbrush );
      NtGdiSelectObject ( hDC, dc->Dc_Attr.hpen );

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

      return objOrg;

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

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

WORD STDCALL
IntGdiSetHookFlags(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;
}


BOOL
STDCALL
NtGdiGetDCDword(
             HDC hDC,
             UINT u,
             DWORD *Result
               )
{
  BOOL Ret = TRUE;
  DC *dc;
  DWORD SafeResult = 0;
  NTSTATUS Status = STATUS_SUCCESS;

  if(!Result)
  {
    SetLastWin32Error(ERROR_INVALID_PARAMETER);
    return FALSE;
  }

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

  switch (u)
  {
    case GdiGetJournal:
      break;
    case GdiGetRelAbs:
      SafeResult = dc->Dc_Attr.lRelAbs;
      break;
    case GdiGetBreakExtra:
      SafeResult = dc->Dc_Attr.lBreakExtra;
      break;
    case GdiGerCharBreak:
      SafeResult = dc->Dc_Attr.cBreak;
      break;
    case GdiGetArcDirection:
      SafeResult = dc->w.ArcDirection;
      break;
    case GdiGetEMFRestorDc:
      break;
    case GdiGetFontLanguageInfo:
      break;
    case GdiGetIsMemDc:
          SafeResult = dc->DC_Type;
      break;
    case GdiGetMapMode:
      SafeResult = dc->Dc_Attr.iMapMode;
      break;
    case GdiGetTextCharExtra:
      SafeResult = dc->Dc_Attr.lTextExtra;
      break;
    default:
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      Ret = FALSE;
      break;
  }

  if (Ret)
  {
    _SEH_TRY
    {
      ProbeForWrite(Result,
                    sizeof(DWORD),
                    1);
      *Result = SafeResult;
    }
    _SEH_HANDLE
    {
      Status = _SEH_GetExceptionCode();
    }
    _SEH_END;
  }

  if(!NT_SUCCESS(Status))
  {
    SetLastNtError(Status);
    DC_UnlockDc(dc);
    return FALSE;
  }

  DC_UnlockDc(dc);
  return Ret;
}
                                        
BOOL
STDCALL
NtGdiGetAndSetDCDword(
                  HDC hDC,
                  UINT u,
                  DWORD dwIn,
                  DWORD *Result
                     )
{
  BOOL Ret = TRUE;
  DC *dc;
  DWORD SafeResult = 0;
  NTSTATUS Status = STATUS_SUCCESS;

  if(!Result)
  {
    SetLastWin32Error(ERROR_INVALID_PARAMETER);
    return FALSE;
  }

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

  switch (u)
  {
    case GdtGetSetCopyCount:
      break;
    case GdiGetSetTextAlign:
      SafeResult = dc->Dc_Attr.lTextAlign;
      dc->Dc_Attr.lTextAlign = dwIn;
      dc->Dc_Attr.flTextAlign = dwIn;
      break;
    case GdiGetSetRelAbs:
      SafeResult = dc->Dc_Attr.lRelAbs;
      dc->Dc_Attr.lRelAbs = dwIn;
      break;
    case GdiGetSetTextCharExtra:
      SafeResult = dc->Dc_Attr.lTextExtra;
      dc->Dc_Attr.lTextExtra = dwIn;
      break;
    case GdiGetSetSelectFont:
      break;
    case GdiGetSetMapperFlagsInternal:
      break;
    case GdiGetSetMapMode:
      SafeResult = dc->Dc_Attr.iMapMode;
      dc->Dc_Attr.iMapMode = dwIn;
      break;
    case GdiGetSetArcDirection:
      if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
      {
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
         Ret = FALSE;
      }                        
      SafeResult = dc->w.ArcDirection;
      dc->w.ArcDirection = dwIn;
      break;
    default:
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      Ret = FALSE;
      break;
  }

  if (Ret)
  {
    _SEH_TRY
    {
      ProbeForWrite(Result,
                    sizeof(DWORD),
                    1);
      *Result = SafeResult;
    }
    _SEH_HANDLE
    {
      Status = _SEH_GetExceptionCode();
    }
    _SEH_END;
  }

  if(!NT_SUCCESS(Status))
  {
    SetLastNtError(Status);
    DC_UnlockDc(dc);
    return FALSE;
  }

  DC_UnlockDc(dc);
  return Ret;
}


DC_SET_MODE( NtGdiSetBkMode, Dc_Attr.jBkMode, TRANSPARENT, OPAQUE )
DC_SET_MODE( NtGdiSetPolyFillMode, Dc_Attr.jFillMode, ALTERNATE, WINDING )
DC_SET_MODE( NtGdiSetROP2, Dc_Attr.jROP2, R2_BLACK, R2_WHITE )
DC_SET_MODE( NtGdiSetStretchBltMode, Dc_Attr.jStretchBltMode, BLACKONWHITE, HALFTONE )

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

HDC FASTCALL
DC_AllocDC(PUNICODE_STRING Driver)
{
  PDC  NewDC;
  HDC  hDC;
  PWSTR Buf = NULL;
//  PDC_ATTR DC_Attr = 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;
  }
#if 0
  PVOID NewMem = NULL;
  ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size
  NTSTATUS Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                                       &NewMem,
                                                             0,
                                                      &MemSize,
                                                    MEM_COMMIT,
                                                PAGE_READWRITE);
  KeEnterCriticalRegion();
  {
    INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC);
    PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];

    if (NT_SUCCESS(Status))
    {
      RtlZeroMemory(NewMem, MemSize);
      Entry->UserData  = NewMem; 
      DPRINT("DC_ATTR allocated! 0x%x\n",NewMem);
    }
    else
    {
       DPRINT("DC_ATTR not allocated!\n");
    }
  }
  KeLeaveCriticalRegion();
#endif  
  NewDC = DC_LockDc(hDC);
  /* FIXME - Handle NewDC == NULL! */
#if 0
  if(NewMem)
  {
     NewDC->pDc_Attr = NewMem; // Store pointer
     DC_Attr = NewMem;
  }
#endif
  if (Driver != NULL)
  {
    RtlCopyMemory(&NewDC->DriverName, Driver, sizeof(UNICODE_STRING));
    NewDC->DriverName.Buffer = Buf;
  }

//  gxf_long a;
//  a.f = 1.0f;

  NewDC->w.xformWorld2Wnd.eM11 = 1.0f;
//  DC_Attr->mxWorldToPage.efM11.lExp  =  XFPEXP(a);
//  DC_Attr->mxWorldToPage.efM11.lMant = XFPMANT(a);

  NewDC->w.xformWorld2Wnd.eM12 = 0.0f; //Already Zero!
  NewDC->w.xformWorld2Wnd.eM21 = 0.0f;

  NewDC->w.xformWorld2Wnd.eM22 = 1.0f;
//  DC_Attr->mxWorldToPage.efM22.lExp  =  XFPEXP(a);
//  DC_Attr->mxWorldToPage.efM22.lMant = XFPMANT(a);
  
  NewDC->w.xformWorld2Wnd.eDx = 0.0f; //Already Zero!
  NewDC->w.xformWorld2Wnd.eDy = 0.0f;

  NewDC->w.xformWorld2Vport = NewDC->w.xformWorld2Wnd;
//  DC_Attr->mxWorldToDevice = DC_Attr->mxWorldToPage; 

  NewDC->w.xformVport2World = NewDC->w.xformWorld2Wnd;
//  DC_Attr->mxDevicetoWorld = DC_Attr->mxWorldToPage; 

  NewDC->w.vport2WorldValid = TRUE;
//  DC_Attr->flXform = DEVICE_TO_PAGE_INVALID; // More research.

  NewDC->Dc_Attr.iMapMode = MM_TEXT;
//  DC_Attr->iMapMode = MM_TEXT;


//// HELP! FLOAT to INT !!!!!!!!!
  NewDC->Dc_Attr.szlWindowExt.cx = 1.0f;
  NewDC->Dc_Attr.szlWindowExt.cy = 1.0f;
  NewDC->Dc_Attr.szlViewportExt.cx = 1.0f;
  NewDC->Dc_Attr.szlViewportExt.cy = 1.0f;

  NewDC->Dc_Attr.crForegroundClr = 0;
//  NewDC->pDc_Attr->ulForegroundClr = 0; // Already Zero
//  NewDC->pDc_Attr->crForegroundClr = 0;

  NewDC->Dc_Attr.crBackgroundClr = 0xffffff;
//  DC_Attr->ulBackgroundClr = 0xffffff;
//  DC_Attr->crBackgroundClr = 0xffffff;

  NewDC->Dc_Attr.hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
  TextIntRealizeFont(NewDC->Dc_Attr.hlfntNew);
//  DC_Attr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT);
  
  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 0
  KeEnterCriticalRegion();
  {
    INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree);
    PGDI_TABLE_ENTRY Entry = &GdiH

⌨️ 快捷键说明

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