4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
17 #define NB_DCE 5 /* Number of DCEs created at startup */
19 extern Display
* display
;
21 static HANDLE firstDCE
= 0;
22 static HDC defaultDCstate
= 0;
25 /***********************************************************************
30 HANDLE
DCE_AllocDCE( DCE_TYPE type
)
33 HANDLE handle
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(DCE
) );
34 if (!handle
) return 0;
35 dce
= (DCE
*) USER_HEAP_ADDR( handle
);
36 if (!(dce
->hdc
= CreateDC( "DISPLAY", NULL
, NULL
, NULL
)))
38 USER_HEAP_FREE( handle
);
43 dce
->inUse
= (type
!= DCE_CACHE_DC
);
46 dce
->hNext
= firstDCE
;
52 /***********************************************************************
55 void DCE_FreeDCE( HANDLE hdce
)
58 HANDLE
*handle
= &firstDCE
;
60 if (!(dce
= (DCE
*) USER_HEAP_ADDR( hdce
))) return;
61 while (*handle
&& (*handle
!= hdce
))
63 DCE
* prev
= (DCE
*) USER_HEAP_ADDR( *handle
);
64 handle
= &prev
->hNext
;
66 if (*handle
== hdce
) *handle
= dce
->hNext
;
68 USER_HEAP_FREE( hdce
);
72 /***********************************************************************
81 for (i
= 0; i
< NB_DCE
; i
++)
83 if (!(handle
= DCE_AllocDCE( DCE_CACHE_DC
))) return;
84 dce
= (DCE
*) USER_HEAP_ADDR( handle
);
85 if (!defaultDCstate
) defaultDCstate
= GetDCState( dce
->hdc
);
90 /***********************************************************************
93 * Return the visible rectangle of a window, i.e. the client or
94 * window area clipped by the client area of all ancestors.
96 static void DCE_GetVisRect( WND
*wndPtr
, BOOL clientArea
, RECT
*lprect
)
100 *lprect
= clientArea
? wndPtr
->rectClient
: wndPtr
->rectWindow
;
101 xoffset
= lprect
->left
;
102 yoffset
= lprect
->top
;
104 while (wndPtr
->dwStyle
& WS_CHILD
)
106 WND
*parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
107 xoffset
+= parentPtr
->rectClient
.left
;
108 yoffset
+= parentPtr
->rectClient
.top
;
109 OffsetRect( lprect
, parentPtr
->rectClient
.left
,
110 parentPtr
->rectClient
.top
);
112 /* Warning!! we assume that IntersectRect() handles the case */
113 /* where the destination is the same as one of the sources. */
114 IntersectRect( lprect
, lprect
, &parentPtr
->rectClient
);
117 OffsetRect( lprect
, -xoffset
, -yoffset
);
121 /***********************************************************************
124 /* Unimplemented flags: DCX_CLIPSIBLINGS, DCX_LOCKWINDOWUPDATE, DCX_PARENTCLIP
126 HDC
GetDCEx( HWND hwnd
, HRGN hrgnClip
, DWORD flags
)
138 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
142 if (flags
& DCX_USESTYLE
)
144 /* Not sure if this is the real meaning of the DCX_USESTYLE flag... */
145 flags
&= ~(DCX_CACHE
| DCX_CLIPCHILDREN
| DCX_CLIPSIBLINGS
);
148 if (!(wndPtr
->flags
& (WIN_CLASS_DC
| WIN_OWN_DC
)))
150 if (wndPtr
->dwStyle
& WS_CLIPCHILDREN
) flags
|= DCX_CLIPCHILDREN
;
151 if (wndPtr
->dwStyle
& WS_CLIPSIBLINGS
) flags
|= DCX_CLIPSIBLINGS
;
153 else flags
|= DCX_CACHE
;
156 if (flags
& DCX_CACHE
)
158 for (hdce
= firstDCE
; (hdce
); hdce
= dce
->hNext
)
160 if (!(dce
= (DCE
*) USER_HEAP_ADDR( hdce
))) return 0;
161 if ((dce
->type
== DCE_CACHE_DC
) && (!dce
->inUse
)) break;
164 else hdce
= wndPtr
->hdce
;
167 dce
= (DCE
*) USER_HEAP_ADDR( hdce
);
168 dce
->hwndCurrent
= hwnd
;
174 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
178 dc
->u
.x
.drawable
= wndPtr
->window
;
179 if (flags
& DCX_WINDOW
)
183 dc
->w
.DCSizeX
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
184 dc
->w
.DCSizeY
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
188 dc
->w
.DCOrgX
= wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
189 dc
->w
.DCOrgY
= wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
190 dc
->w
.DCSizeX
= wndPtr
->rectClient
.right
- wndPtr
->rectClient
.left
;
191 dc
->w
.DCSizeY
= wndPtr
->rectClient
.bottom
- wndPtr
->rectClient
.top
;
194 DCE_GetVisRect( wndPtr
, !(flags
& DCX_WINDOW
), &clipRect
);
195 IntersectVisRect( hdc
, clipRect
.left
, clipRect
.top
,
196 clipRect
.right
, clipRect
.bottom
);
198 else dc
->u
.x
.drawable
= rootWindow
;
200 if (flags
& DCX_CLIPCHILDREN
)
201 XSetSubwindowMode( display
, dc
->u
.x
.gc
, ClipByChildren
);
202 else XSetSubwindowMode( display
, dc
->u
.x
.gc
, IncludeInferiors
);
204 if ((flags
& DCX_INTERSECTRGN
) || (flags
& DCX_EXCLUDERGN
))
206 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
209 if (CombineRgn( hrgn
, InquireVisRgn(hdc
), hrgnClip
,
210 (flags
& DCX_INTERSECTRGN
) ? RGN_AND
: RGN_DIFF
)) {
211 SelectVisRgn( hdc
, hrgn
);
213 DeleteObject( hrgn
);
218 printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd
, hrgnClip
, flags
, hdc
);
224 /***********************************************************************
227 HDC
GetDC( HWND hwnd
)
229 return GetDCEx( hwnd
, 0, DCX_USESTYLE
);
233 /***********************************************************************
234 * GetWindowDC (USER.67)
236 HDC
GetWindowDC( HWND hwnd
)
238 int flags
= DCX_CACHE
| DCX_WINDOW
;
242 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
243 if (wndPtr
->dwStyle
& WS_CLIPCHILDREN
) flags
|= DCX_CLIPCHILDREN
;
244 if (wndPtr
->dwStyle
& WS_CLIPSIBLINGS
) flags
|= DCX_CLIPSIBLINGS
;
246 return GetDCEx( hwnd
, 0, flags
);
250 /***********************************************************************
251 * ReleaseDC (USER.68)
253 int ReleaseDC( HWND hwnd
, HDC hdc
)
259 printf( "ReleaseDC: %d %d\n", hwnd
, hdc
);
262 for (hdce
= firstDCE
; (hdce
); hdce
= dce
->hNext
)
264 if (!(dce
= (DCE
*) USER_HEAP_ADDR( hdce
))) return 0;
265 if (dce
->inUse
&& (dce
->hdc
== hdc
)) break;
269 if (dce
->type
== DCE_CACHE_DC
)
271 SetDCState( dce
->hdc
, defaultDCstate
);