4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
16 #define NB_DCE 5 /* Number of DCEs created at startup */
18 extern Display
* display
;
20 static HANDLE firstDCE
= 0;
21 static HDC defaultDCstate
= 0;
24 /***********************************************************************
29 HANDLE
DCE_AllocDCE( DCE_TYPE type
)
32 HANDLE handle
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(DCE
) );
33 if (!handle
) return 0;
34 dce
= (DCE
*) USER_HEAP_ADDR( handle
);
35 if (!(dce
->hdc
= CreateDC( "DISPLAY", NULL
, NULL
, NULL
)))
37 USER_HEAP_FREE( handle
);
42 dce
->inUse
= (type
!= DCE_CACHE_DC
);
45 dce
->hNext
= firstDCE
;
51 /***********************************************************************
54 void DCE_FreeDCE( HANDLE hdce
)
57 HANDLE
*handle
= &firstDCE
;
59 if (!(dce
= (DCE
*) USER_HEAP_ADDR( hdce
))) return;
60 while (*handle
&& (*handle
!= hdce
))
62 DCE
* prev
= (DCE
*) USER_HEAP_ADDR( *handle
);
63 handle
= &prev
->hNext
;
65 if (*handle
== hdce
) *handle
= dce
->hNext
;
67 USER_HEAP_FREE( hdce
);
71 /***********************************************************************
80 for (i
= 0; i
< NB_DCE
; i
++)
82 if (!(handle
= DCE_AllocDCE( DCE_CACHE_DC
))) return;
83 dce
= (DCE
*) USER_HEAP_ADDR( handle
);
84 if (!defaultDCstate
) defaultDCstate
= GetDCState( dce
->hdc
);
89 /***********************************************************************
92 * Return the visible rectangle of a window, i.e. the client or
93 * window area clipped by the client area of all ancestors.
95 static void DCE_GetVisRect( WND
*wndPtr
, BOOL clientArea
, RECT
*lprect
)
99 *lprect
= clientArea
? wndPtr
->rectClient
: wndPtr
->rectWindow
;
100 xoffset
= lprect
->left
;
101 yoffset
= lprect
->top
;
103 while (wndPtr
->dwStyle
& WS_CHILD
)
105 WND
*parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
106 xoffset
+= parentPtr
->rectClient
.left
;
107 yoffset
+= parentPtr
->rectClient
.top
;
108 OffsetRect( lprect
, parentPtr
->rectClient
.left
,
109 parentPtr
->rectClient
.top
);
111 /* Warning!! we assume that IntersectRect() handles the case */
112 /* where the destination is the same as one of the sources. */
113 IntersectRect( lprect
, lprect
, &parentPtr
->rectClient
);
116 OffsetRect( lprect
, -xoffset
, -yoffset
);
120 /***********************************************************************
123 /* Unimplemented flags: DCX_CLIPSIBLINGS, DCX_LOCKWINDOWUPDATE, DCX_PARENTCLIP
125 HDC
GetDCEx( HWND hwnd
, HRGN hrgnClip
, DWORD flags
)
136 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
140 if (flags
& DCX_USESTYLE
)
142 /* Not sure if this is the real meaning of the DCX_USESTYLE flag... */
143 flags
&= ~(DCX_CACHE
| DCX_CLIPCHILDREN
| DCX_CLIPSIBLINGS
);
146 if (!(wndPtr
->flags
& (WIN_CLASS_DC
| WIN_OWN_DC
)))
148 if (wndPtr
->dwStyle
& WS_CLIPCHILDREN
) flags
|= DCX_CLIPCHILDREN
;
149 if (wndPtr
->dwStyle
& WS_CLIPSIBLINGS
) flags
|= DCX_CLIPSIBLINGS
;
151 else flags
|= DCX_CACHE
;
154 if (flags
& DCX_CACHE
)
156 for (hdce
= firstDCE
; (hdce
); hdce
= dce
->hNext
)
158 if (!(dce
= (DCE
*) USER_HEAP_ADDR( hdce
))) return 0;
159 if ((dce
->type
== DCE_CACHE_DC
) && (!dce
->inUse
)) break;
162 else hdce
= wndPtr
->hdce
;
165 dce
= (DCE
*) USER_HEAP_ADDR( hdce
);
166 dce
->hwndCurrent
= hwnd
;
172 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
176 dc
->u
.x
.drawable
= wndPtr
->window
;
177 if (flags
& DCX_WINDOW
)
181 dc
->w
.DCSizeX
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
182 dc
->w
.DCSizeY
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
186 dc
->w
.DCOrgX
= wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
187 dc
->w
.DCOrgY
= wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
188 dc
->w
.DCSizeX
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
189 dc
->w
.DCSizeY
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
192 DCE_GetVisRect( wndPtr
, !(flags
& DCX_WINDOW
), &clipRect
);
193 IntersectVisRect( hdc
, clipRect
.left
, clipRect
.top
,
194 clipRect
.right
, clipRect
.bottom
);
196 else dc
->u
.x
.drawable
= rootWindow
;
198 if (flags
& DCX_CLIPCHILDREN
)
199 XSetSubwindowMode( display
, dc
->u
.x
.gc
, ClipByChildren
);
200 else XSetSubwindowMode( display
, dc
->u
.x
.gc
, IncludeInferiors
);
202 if ((flags
& DCX_INTERSECTRGN
) || (flags
& DCX_EXCLUDERGN
))
204 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
207 if (CombineRgn( hrgn
, InquireVisRgn(hdc
), hrgnClip
,
208 (flags
& DCX_INTERSECTRGN
) ? RGN_AND
: RGN_DIFF
))
209 SelectVisRgn( hdc
, hrgn
);
210 DeleteObject( hrgn
);
215 printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd
, hrgnClip
, flags
, hdc
);
221 /***********************************************************************
224 HDC
GetDC( HWND hwnd
)
226 return GetDCEx( hwnd
, 0, DCX_USESTYLE
);
230 /***********************************************************************
231 * GetWindowDC (USER.67)
233 HDC
GetWindowDC( HWND hwnd
)
235 int flags
= DCX_CACHE
| DCX_WINDOW
;
239 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
240 if (wndPtr
->dwStyle
& WS_CLIPCHILDREN
) flags
|= DCX_CLIPCHILDREN
;
241 if (wndPtr
->dwStyle
& WS_CLIPSIBLINGS
) flags
|= DCX_CLIPSIBLINGS
;
243 return GetDCEx( hwnd
, 0, flags
);
247 /***********************************************************************
248 * ReleaseDC (USER.68)
250 int ReleaseDC( HWND hwnd
, HDC hdc
)
256 printf( "ReleaseDC: %d %d\n", hwnd
, hdc
);
259 for (hdce
= firstDCE
; (hdce
); hdce
= dce
->hNext
)
261 if (!(dce
= (DCE
*) USER_HEAP_ADDR( hdce
))) return 0;
262 if (dce
->inUse
&& (dce
->hdc
== hdc
)) break;
266 if (dce
->type
== DCE_CACHE_DC
)
268 SetDCState( dce
->hdc
, defaultDCstate
);