DCE

From ReactOS Wiki
Revision as of 19:56, 13 November 2018 by Ekohl (talk | contribs) (Try to fix the introduction to the page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

This page attempts to describe how DCs (Display Contexts) are implemented in ReactOS.

Basic framework

Code

The DCE system is defined in subsystems/win32/win32k/ntuser/windc.c and subsystems/win32/win32k/include/dce.h . Most of it was taken from Wine but it hasn't been kept in sync and ReactOS has made private changes.

Storage

The DCE's are kept in a global single linked list that starts with the FirstDce global var. It should be protected by the DceListLock mutex (but isn't).

DCE types

There are three types of DCE's:

DCE_WINDOW_DC 
For windows that have the CS_OWNDC style, they get their own so called private DC.
DCE_CLASS_DC 
For classes whose windows have the CS_CLASSDC style, they get a DC that is shared between these windows. This is not implemented yet.
DCE_CACHE_DC 
This encompasses two types actually: DC's that have been requested for windows that have neither CS_OWNDC or CS_CLASSDC (or by using DCX_CACHE with GetDCEx). When these are released, they stay DCE_CACHE_DC's, but now they do not really belong to a window anymore. A DC a program gets this way is called a common DC.

Windows supports these DC types:

Generic device context
For drawing on a device, bypassing the window manager (the device would most likely be a printer)
Window device context
For drawing on or in windows.
Information context
like the generic device context, but you can't use it to draw. You can use it to query a device for information (like the size of paper a printer supports, or the resolution a video driver supports)
Memory device context
like the generic device context, but draws into a piece of memory (a device independent or dependent bitmap) instead.
Metafile device context
Special device context for recording and playing back metafiles (wmf).

DCE creation

A DCE is created in different situations:

  • A window having the CS_OWNDC style is created
  • A window having the CS_CLASSDC style is created and the class does not have a DCE yet.
  • A program requests a DC and the window doesn't have CS_OWNDC or CS_CLASSDC, or the program states that it wants one from the cache (DCX_CACHE).

If the program requests a DC from the cache, it must release it again using ReleaseDC. It is then cleared and put in the cache to be used again (unless it was requested with DCX_NORESETATTRS, which we don't handle too).

DCE destroying

A DCE is released when:

  • The program releases it using ReleaseDC (or something similar like EndPaint) and it's a common DC; nothing happens for the other types.
  • It's attached to a window (by means of CS_OWNDC or similar) and the window is destroyed
  • It was requested by a program for a window and the window is destroyed. This causes a warning, as the DC was leaked. This is a pretty serious error, especially if the code should run on Win9x because these systems only have 5 common DC's available, and will just refuse new ones if they have been used up.

Common DC's do not get destroyed when they are released, they go to the cache instead. The other ones are destroyed when they are no longer in use.

DCE contents

What is in a DCE:

  • A pointer to the next one, for the single linked list.
  • A handle to the DC this DCE is for.
  • A handle to the window the DC is for.
  • Another handle that isn't used anywhere
  • A handle to a clip region
  • A description of the type it is
  • Some flags about the state of the DCE
  • A handle to itself.

Some of the flags are:

DCX_DCEEMPTY 
This DCE does not contain a DC
DCX_DCEBUSY 
This DCE is in use by a window
DCX_DCEDIRTY 
Destroy the DC if it is released.
DCX_KEEPCLIPRGN 
Do not destroy the clip region
DCX_WINDOWPAINT 
BeginPaint is in effect (this is set by user32). Apparently this is only for making sure the clip region is destroyed with the DCE.

The rest

Some things are done by using hooks, I didn't find out how that works exactly.

The DCE contains a clip region that must be kept up-to-date when windows move or the z-order changes.

The way Windows handles the DC cache is mostly undocumented. The good news is that because of this, few applications use most of the DC features. The bad news is that it's hard to create a compatible implementation.