First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xgl / xglarea.c
blobcdf652d0f6ccf81ff256eb20e6d2e1617882db2d
1 /*
2 * Copyright © 2005 Novell, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Novell, Inc. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * Novell, Inc. makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
15 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: David Reveman <davidr@novell.com>
26 #include "xgl.h"
28 static Bool
29 xglAreaMoveIn (xglAreaPtr pArea,
30 pointer closure)
32 pArea->closure = closure;
33 pArea->state = xglAreaOccupied;
35 return (*pArea->pRoot->funcs->MoveIn) (pArea, closure);
38 static void
39 xglAreaMoveOut (xglAreaPtr pArea)
41 (*pArea->pRoot->funcs->MoveOut) (pArea, pArea->closure);
43 pArea->closure = (pointer) 0;
44 pArea->state = xglAreaAvailable;
47 static xglAreaPtr
48 xglAreaCreate (xglRootAreaPtr pRoot,
49 int level,
50 int x,
51 int y,
52 int width,
53 int height)
55 xglAreaPtr pArea;
56 int n = 4;
58 pArea = xalloc (sizeof (xglAreaRec) + pRoot->devPrivateSize);
59 if (!pArea)
60 return NULL;
62 pArea->level = level;
63 pArea->x = x;
64 pArea->y = y;
65 pArea->width = width;
66 pArea->height = height;
67 pArea->pRoot = pRoot;
68 pArea->closure = (pointer) 0;
69 pArea->state = xglAreaAvailable;
71 while (n--)
72 pArea->pArea[n] = NULL;
74 if (pRoot->devPrivateSize)
75 pArea->devPrivate.ptr = pArea + 1;
76 else
77 pArea->devPrivate.ptr = (pointer) 0;
79 if (!(*pArea->pRoot->funcs->Create) (pArea))
81 free (pArea);
82 return NULL;
85 return pArea;
88 static void
89 xglAreaDestroy (xglAreaPtr pArea)
91 if (!pArea)
92 return;
94 if (pArea->state == xglAreaOccupied)
96 xglAreaMoveOut (pArea);
98 else
100 int n = 4;
102 while (n--)
103 xglAreaDestroy (pArea->pArea[n]);
106 xfree (pArea);
109 static xglAreaPtr
110 xglAreaGetTopScoredSubArea (xglAreaPtr pArea)
112 if (!pArea)
113 return NULL;
115 switch (pArea->state) {
116 case xglAreaOccupied:
117 return pArea;
118 case xglAreaAvailable:
119 break;
120 case xglAreaDivided: {
121 xglAreaPtr tmp, top = NULL;
122 int i;
124 for (i = 0; i < 4; i++)
126 tmp = xglAreaGetTopScoredSubArea (pArea->pArea[i]);
127 if (tmp && top)
129 if ((*pArea->pRoot->funcs->CompareScore) (tmp,
130 tmp->closure,
131 top->closure) > 0)
132 top = tmp;
134 else if (tmp)
136 top = tmp;
139 return top;
143 return NULL;
146 static Bool
147 xglAreaFind (xglAreaPtr pArea,
148 int width,
149 int height,
150 Bool kickOut,
151 pointer closure)
153 if (pArea->width < width || pArea->height < height)
154 return FALSE;
156 switch (pArea->state) {
157 case xglAreaOccupied:
158 if (kickOut)
160 if ((*pArea->pRoot->funcs->CompareScore) (pArea,
161 pArea->closure,
162 closure) >= 0)
163 return FALSE;
165 xglAreaMoveOut (pArea);
166 } else
167 return FALSE;
169 /* fall-through */
170 case xglAreaAvailable:
172 if (pArea->level == pArea->pRoot->maxLevel ||
173 (pArea->width == width && pArea->height == height))
175 if (xglAreaMoveIn (pArea, closure))
176 return TRUE;
178 else
180 int dx[4], dy[4], w[4], h[4], i;
182 dx[0] = dx[2] = dy[0] = dy[1] = 0;
184 w[0] = w[2] = dx[1] = dx[3] = width;
185 h[0] = h[1] = dy[2] = dy[3] = height;
187 w[1] = w[3] = pArea->width - width;
188 h[2] = h[3] = pArea->height - height;
190 for (i = 0; i < 2; i++)
192 if (w[i])
193 pArea->pArea[i] =
194 xglAreaCreate (pArea->pRoot,
195 pArea->level + 1,
196 pArea->x + dx[i],
197 pArea->y + dy[i],
198 w[i], h[i]);
201 for (; i < 4; i++)
203 if (w[i] && h[i])
204 pArea->pArea[i] =
205 xglAreaCreate (pArea->pRoot,
206 pArea->level + 1,
207 pArea->x + dx[i],
208 pArea->y + dy[i],
209 w[i], h[i]);
212 pArea->state = xglAreaDivided;
214 if (xglAreaFind (pArea->pArea[0], width, height, kickOut, closure))
215 return TRUE;
217 } break;
218 case xglAreaDivided:
220 xglAreaPtr topArea;
221 int i, rejected = FALSE;
223 for (i = 0; i < 4; i++)
225 if (pArea->pArea[i])
227 if (pArea->pArea[i]->width >= width &&
228 pArea->pArea[i]->height >= height)
230 if (xglFindArea (pArea->pArea[i], width, height, kickOut,
231 closure))
232 return TRUE;
234 rejected = TRUE;
239 if (rejected)
240 return FALSE;
242 topArea = xglAreaGetTopScoredSubArea (pArea);
243 if (topArea)
245 if (kickOut)
247 if ((*pArea->pRoot->funcs->CompareScore) (topArea,
248 topArea->closure,
249 closure) >= 0)
250 return FALSE;
251 } else
252 return FALSE;
255 for (i = 0; i < 4; i++)
257 xglAreaDestroy (pArea->pArea[i]);
258 pArea->pArea[i] = NULL;
261 pArea->closure = (pointer) 0;
262 pArea->state = xglAreaAvailable;
263 if (xglFindArea (pArea, width, height, TRUE, closure))
264 return TRUE;
266 } break;
269 return FALSE;
272 Bool
273 xglRootAreaInit (xglRootAreaPtr pRoot,
274 int maxLevel,
275 int width,
276 int height,
277 int devPrivateSize,
278 xglAreaFuncsPtr funcs,
279 pointer closure)
281 pRoot->maxLevel = maxLevel;
282 pRoot->funcs = funcs;
283 pRoot->devPrivateSize = devPrivateSize;
284 pRoot->closure = closure;
286 pRoot->pArea = xglAreaCreate (pRoot, 0, 0, 0, width, height);
287 if (!pRoot->pArea)
288 return FALSE;
290 return TRUE;
293 void
294 xglRootAreaFini (xglRootAreaPtr pRoot)
296 xglAreaDestroy (pRoot->pArea);
299 void
300 xglLeaveArea (xglAreaPtr pArea)
302 xglAreaMoveOut (pArea);
305 void
306 xglWithdrawArea (xglAreaPtr pArea)
308 pArea->closure = NULL;
309 pArea->state = xglAreaAvailable;
312 Bool
313 xglFindArea (xglAreaPtr pArea,
314 int width,
315 int height,
316 Bool kickOut,
317 pointer closure)
319 if (width < 1 || height < 0)
320 return FALSE;
322 return xglAreaFind (pArea, width, height, kickOut, closure);