Release 940912
[wine/gsoc-2012-control.git] / windows / dce.c
blob2148af1e9cdbbf4651f6b5f237a09105558c2f50
1 /*
2 * USER DCE functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include "dce.h"
10 #include "class.h"
11 #include "win.h"
12 #include "gdi.h"
13 #include "user.h"
14 #include "icon.h"
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 /***********************************************************************
26 * DCE_AllocDCE
28 * Allocate a new DCE.
30 HANDLE DCE_AllocDCE( DCE_TYPE type )
32 DCE * dce;
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 );
39 return 0;
41 dce->hwndCurrent = 0;
42 dce->type = type;
43 dce->inUse = (type != DCE_CACHE_DC);
44 dce->xOrigin = 0;
45 dce->yOrigin = 0;
46 dce->hNext = firstDCE;
47 firstDCE = handle;
48 return handle;
52 /***********************************************************************
53 * DCE_FreeDCE
55 void DCE_FreeDCE( HANDLE hdce )
57 DCE * dce;
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;
67 DeleteDC( dce->hdc );
68 USER_HEAP_FREE( hdce );
72 /***********************************************************************
73 * DCE_Init
75 void DCE_Init()
77 int i;
78 HANDLE handle;
79 DCE * dce;
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 /***********************************************************************
91 * DCE_GetVisRect
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 )
98 int xoffset, yoffset;
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 );
115 wndPtr = parentPtr;
117 OffsetRect( lprect, -xoffset, -yoffset );
121 /***********************************************************************
122 * GetDCEx (USER.359)
124 /* Unimplemented flags: DCX_CLIPSIBLINGS, DCX_LOCKWINDOWUPDATE, DCX_PARENTCLIP
126 HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
128 HANDLE hdce;
129 RECT clipRect;
130 HDC hdc = 0;
131 DCE * dce;
132 DC * dc;
133 WND * wndPtr;
134 ICONALLOC *lpico;
136 if (hwnd)
138 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
140 else wndPtr = NULL;
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);
146 if (wndPtr)
148 if (!(wndPtr->flags & (WIN_CLASS_DC | WIN_OWN_DC)))
149 flags |= DCX_CACHE;
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;
166 if (!hdce) return 0;
167 dce = (DCE *) USER_HEAP_ADDR( hdce );
168 dce->hwndCurrent = hwnd;
169 dce->inUse = TRUE;
170 hdc = dce->hdc;
172 /* Initialize DC */
174 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
176 if (wndPtr)
178 dc->u.x.drawable = wndPtr->window;
179 if (flags & DCX_WINDOW)
181 dc->w.DCOrgX = 0;
182 dc->w.DCOrgY = 0;
183 dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
184 dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
186 else
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 );
207 if (hrgn)
209 if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip,
210 (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF )) {
211 SelectVisRgn( hdc, hrgn );
213 DeleteObject( hrgn );
217 #ifdef DEBUG_DC
218 printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd, hrgnClip, flags, hdc);
219 #endif
220 return hdc;
224 /***********************************************************************
225 * GetDC (USER.66)
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;
239 if (hwnd)
241 WND * wndPtr;
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 )
255 HANDLE hdce;
256 DCE * dce = NULL;
258 #ifdef DEBUG_DC
259 printf( "ReleaseDC: %d %d\n", hwnd, hdc );
260 #endif
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;
267 if (!hdce) return 0;
269 if (dce->type == DCE_CACHE_DC)
271 SetDCState( dce->hdc, defaultDCstate );
272 dce->inUse = FALSE;
274 return 1;