Release 940201
[wine.git] / windows / dce.c
blob5aef283c7f7141f86f552d4e6e93125a6f23ba6a
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"
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 /***********************************************************************
25 * DCE_AllocDCE
27 * Allocate a new DCE.
29 HANDLE DCE_AllocDCE( DCE_TYPE type )
31 DCE * dce;
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 );
38 return 0;
40 dce->hwndCurrent = 0;
41 dce->type = type;
42 dce->inUse = (type != DCE_CACHE_DC);
43 dce->xOrigin = 0;
44 dce->yOrigin = 0;
45 dce->hNext = firstDCE;
46 firstDCE = handle;
47 return handle;
51 /***********************************************************************
52 * DCE_FreeDCE
54 void DCE_FreeDCE( HANDLE hdce )
56 DCE * dce;
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;
66 DeleteDC( dce->hdc );
67 USER_HEAP_FREE( hdce );
71 /***********************************************************************
72 * DCE_Init
74 void DCE_Init()
76 int i;
77 HANDLE handle;
78 DCE * dce;
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 /***********************************************************************
90 * GetDCEx (USER.359)
92 /* Unimplemented flags: DCX_CLIPSIBLINGS, DCX_LOCKWINDOWUPDATE, DCX_PARENTCLIP
94 HDC GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags )
96 HANDLE hdce;
97 HDC hdc = 0;
98 DCE * dce;
99 DC * dc;
100 WND * wndPtr;
102 if (hwnd)
104 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
106 else wndPtr = NULL;
108 if (flags & DCX_USESTYLE)
110 /* Not sure if this is the real meaning of the DCX_USESTYLE flag... */
111 flags &= ~(DCX_CACHE | DCX_CLIPCHILDREN | DCX_CLIPSIBLINGS);
112 if (wndPtr)
114 if (!(wndPtr->flags & (WIN_CLASS_DC | WIN_OWN_DC)))
115 flags |= DCX_CACHE;
116 if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN;
117 if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
119 else flags |= DCX_CACHE;
122 if (flags & DCX_CACHE)
124 for (hdce = firstDCE; (hdce); hdce = dce->hNext)
126 if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
127 if ((dce->type == DCE_CACHE_DC) && (!dce->inUse)) break;
130 else hdce = wndPtr->hdce;
132 if (!hdce) return 0;
133 dce = (DCE *) USER_HEAP_ADDR( hdce );
134 dce->hwndCurrent = hwnd;
135 dce->inUse = TRUE;
136 hdc = dce->hdc;
138 /* Initialize DC */
140 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
142 if (wndPtr)
144 dc->u.x.drawable = wndPtr->window;
145 if (flags & DCX_WINDOW)
147 dc->w.DCOrgX = 0;
148 dc->w.DCOrgY = 0;
149 dc->w.DCSizeX = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
150 dc->w.DCSizeY = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
152 else
154 dc->w.DCOrgX = wndPtr->rectClient.left - wndPtr->rectWindow.left;
155 dc->w.DCOrgY = wndPtr->rectClient.top - wndPtr->rectWindow.top;
156 dc->w.DCSizeX = wndPtr->rectClient.right - wndPtr->rectClient.left;
157 dc->w.DCSizeY = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
158 IntersectVisRect( hdc, 0, 0, dc->w.DCSizeX, dc->w.DCSizeY );
161 else dc->u.x.drawable = DefaultRootWindow( display );
163 if (flags & DCX_CLIPCHILDREN)
164 XSetSubwindowMode( display, dc->u.x.gc, ClipByChildren );
165 else XSetSubwindowMode( display, dc->u.x.gc, IncludeInferiors);
167 if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
169 HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
170 if (hrgn)
172 if (CombineRgn( hrgn, InquireVisRgn(hdc), hrgnClip,
173 (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF ))
174 SelectVisRgn( hdc, hrgn );
175 DeleteObject( hrgn );
179 #ifdef DEBUG_DC
180 printf( "GetDCEx(%d,%d,0x%x): returning %d\n", hwnd, hrgnClip, flags, hdc);
181 #endif
182 return hdc;
186 /***********************************************************************
187 * GetDC (USER.66)
189 HDC GetDC( HWND hwnd )
191 return GetDCEx( hwnd, 0, DCX_USESTYLE );
195 /***********************************************************************
196 * GetWindowDC (USER.67)
198 HDC GetWindowDC( HWND hwnd )
200 int flags = DCX_CACHE | DCX_WINDOW;
201 if (hwnd)
203 WND * wndPtr;
204 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
205 if (wndPtr->dwStyle & WS_CLIPCHILDREN) flags |= DCX_CLIPCHILDREN;
206 if (wndPtr->dwStyle & WS_CLIPSIBLINGS) flags |= DCX_CLIPSIBLINGS;
208 return GetDCEx( hwnd, 0, flags );
212 /***********************************************************************
213 * ReleaseDC (USER.68)
215 int ReleaseDC( HWND hwnd, HDC hdc )
217 HANDLE hdce;
218 DCE * dce = NULL;
220 #ifdef DEBUG_DC
221 printf( "ReleaseDC: %d %d\n", hwnd, hdc );
222 #endif
224 for (hdce = firstDCE; (hdce); hdce = dce->hNext)
226 if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
227 if (dce->inUse && (dce->hdc == hdc)) break;
229 if (!hdce) return 0;
231 if (dce->type == DCE_CACHE_DC)
233 SetDCState( dce->hdc, defaultDCstate );
234 dce->inUse = FALSE;
236 return 1;