1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | #ifdef HAVE_CONFIG_H1 |
51 | #include <config.h> |
52 | #endif |
53 | #include <X11/IntrinsicP.h> |
54 | #include <X11/StringDefs.h> |
55 | #include <X11/Xaw/XawInit.h> |
56 | #include <X11/Xaw/Cardinals.h> |
57 | #include <X11/Xaw/TreeP.h> |
58 | #include "Private.h" |
59 | |
60 | #define IsHorizontal(tw)((tw)->tree.gravity == 4 || (tw)->tree.gravity == 6) ((tw)->tree.gravity == WestGravity4 || \ |
61 | (tw)->tree.gravity == EastGravity6) |
62 | |
63 | |
64 | |
65 | |
66 | static void XawTreeChangeManaged(Widget); |
67 | static void XawTreeClassInitialize(void); |
68 | static void XawTreeConstraintDestroy(Widget); |
69 | static void XawTreeConstraintInitialize(Widget, Widget, ArgList, Cardinal*); |
70 | static Boolean XawTreeConstraintSetValues(Widget, Widget, Widget, |
71 | ArgList, Cardinal*); |
72 | static void XawTreeDestroy(Widget); |
73 | static XtGeometryResult XawTreeGeometryManager(Widget, XtWidgetGeometry*, |
74 | XtWidgetGeometry*); |
75 | static void XawTreeInitialize(Widget, Widget, ArgList, Cardinal*); |
76 | static XtGeometryResult XawTreeQueryGeometry(Widget, XtWidgetGeometry*, |
77 | XtWidgetGeometry*); |
78 | static void XawTreeRedisplay(Widget, XEvent*, Region); |
79 | static Boolean XawTreeSetValues(Widget, Widget, Widget, ArgList, Cardinal*); |
80 | |
81 | |
82 | |
83 | |
84 | static void arrange_subtree(TreeWidget, Widget, int, int, int); |
85 | static void check_gravity(TreeWidget, XtGravity); |
86 | static void compute_bounding_box_subtree(TreeWidget, Widget, int); |
87 | static void delete_node(Widget, Widget); |
88 | static GC get_tree_gc(TreeWidget); |
89 | static void initialize_dimensions(Dimension**, int*, int); |
90 | static void insert_node(Widget, Widget); |
91 | static void layout_tree(TreeWidget, Boolint); |
92 | static void set_positions(TreeWidget, Widget, int); |
93 | static void set_tree_size(TreeWidget, Boolint, unsigned int, unsigned int); |
94 | |
95 | |
96 | |
97 | |
98 | |
99 | |
100 | |
101 | |
102 | static XtResource resources[] = { |
103 | { XtNautoReconfigure"autoReconfigure", XtCAutoReconfigure"AutoReconfigure", XtRBoolean((char*)&XtStrings[1561]), sizeof (Boolean), |
104 | XtOffsetOf(TreeRec, tree.auto_reconfigure)__builtin_offsetof(TreeRec, tree.auto_reconfigure), XtRImmediate((char*)&XtStrings[1695]), |
105 | (XtPointer) FALSE0 }, |
106 | { XtNhSpace((char*)&XtStrings[251]), XtCHSpace((char*)&XtStrings[1058]), XtRDimension((char*)&XtStrings[1618]), sizeof (Dimension), |
107 | XtOffsetOf(TreeRec, tree.hpad)__builtin_offsetof(TreeRec, tree.hpad), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0 }, |
108 | { XtNvSpace((char*)&XtStrings[865]), XtCVSpace((char*)&XtStrings[1503]), XtRDimension((char*)&XtStrings[1618]), sizeof (Dimension), |
109 | XtOffsetOf(TreeRec, tree.vpad)__builtin_offsetof(TreeRec, tree.vpad), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0 }, |
110 | { XtNforeground((char*)&XtStrings[214]), XtCForeground((char*)&XtStrings[1022]), XtRPixel((char*)&XtStrings[1754]), sizeof (Pixel), |
111 | XtOffsetOf(TreeRec, tree.foreground)__builtin_offsetof(TreeRec, tree.foreground), XtRString((char*)&XtStrings[1797]), |
112 | XtDefaultForeground"XtDefaultForeground"}, |
113 | { XtNlineWidth"lineWidth", XtCLineWidth"LineWidth", XtRDimension((char*)&XtStrings[1618]), sizeof (Dimension), |
114 | XtOffsetOf(TreeRec, tree.line_width)__builtin_offsetof(TreeRec, tree.line_width), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) 0 }, |
115 | { XtNgravity"gravity", XtCGravity"Gravity", XtRGravity((char*)&XtStrings[2042]), sizeof (XtGravity), |
116 | XtOffsetOf(TreeRec, tree.gravity)__builtin_offsetof(TreeRec, tree.gravity), XtRImmediate((char*)&XtStrings[1695]), |
117 | (XtPointer) WestGravity4 }, |
118 | #ifndef OLDXAW1 |
119 | { XawNdisplayList, XawCDisplayList, XawRDisplayList, sizeof(XawDisplayList*), |
120 | XtOffsetOf(TreeRec, tree.display_list)__builtin_offsetof(TreeRec, tree.display_list), XtRImmediate((char*)&XtStrings[1695]), |
121 | NULL((void*)0) }, |
122 | #endif |
123 | }; |
124 | |
125 | |
126 | |
127 | |
128 | |
129 | static XtResource treeConstraintResources[] = { |
130 | { XtNtreeParent"treeParent", XtCTreeParent"TreeParent", XtRWidget((char*)&XtStrings[1865]), sizeof (Widget), |
131 | XtOffsetOf(TreeConstraintsRec, tree.parent)__builtin_offsetof(TreeConstraintsRec, tree.parent), XtRImmediate((char*)&XtStrings[1695]), NULL((void*)0) }, |
132 | { XtNtreeGC"treeGC", XtCTreeGC"TreeGC", XtRGC"GC", sizeof(GC), |
133 | XtOffsetOf(TreeConstraintsRec, tree.gc)__builtin_offsetof(TreeConstraintsRec, tree.gc), XtRImmediate((char*)&XtStrings[1695]), NULL((void*)0) }, |
134 | }; |
135 | |
136 | |
137 | TreeClassRec treeClassRec = { |
138 | { |
139 | |
140 | (WidgetClass) &constraintClassRec, |
141 | "Tree", |
142 | sizeof(TreeRec), |
143 | XawTreeClassInitialize, |
144 | NULL((void*)0), |
145 | FALSE0, |
146 | XawTreeInitialize, |
147 | NULL((void*)0), |
148 | XtInheritRealize((XtRealizeProc) _XtInherit), |
149 | NULL((void*)0), |
150 | 0, |
151 | resources, |
152 | XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), |
153 | NULLQUARK((XrmQuark) 0), |
154 | TRUE1, |
155 | TRUE1, |
156 | TRUE1, |
157 | TRUE1, |
158 | XawTreeDestroy, |
159 | NULL((void*)0), |
160 | XawTreeRedisplay, |
161 | XawTreeSetValues, |
162 | NULL((void*)0), |
163 | XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit), |
164 | NULL((void*)0), |
165 | NULL((void*)0), |
166 | XtVersion(11 * 1000 + 6), |
167 | NULL((void*)0), |
168 | NULL((void*)0), |
169 | XawTreeQueryGeometry, |
170 | NULL((void*)0), |
171 | NULL((void*)0), |
172 | }, |
173 | { |
174 | |
175 | XawTreeGeometryManager, |
176 | XawTreeChangeManaged, |
177 | XtInheritInsertChild((XtWidgetProc) _XtInherit), |
178 | XtInheritDeleteChild((XtWidgetProc) _XtInherit), |
179 | NULL((void*)0), |
180 | }, |
181 | { |
182 | |
183 | treeConstraintResources, |
184 | XtNumber(treeConstraintResources)((Cardinal) (sizeof(treeConstraintResources) / sizeof(treeConstraintResources [0]))), |
185 | sizeof(TreeConstraintsRec), |
186 | XawTreeConstraintInitialize, |
187 | XawTreeConstraintDestroy, |
188 | XawTreeConstraintSetValues, |
189 | NULL((void*)0), |
190 | }, |
191 | { |
192 | |
193 | NULL((void*)0), |
194 | } |
195 | }; |
196 | |
197 | WidgetClass treeWidgetClass = (WidgetClass) &treeClassRec; |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | static void |
207 | initialize_dimensions(Dimension **listp, int *sizep, int n) |
208 | { |
209 | int i; |
210 | Dimension *l; |
211 | |
212 | if (!*listp) { |
213 | *listp = (Dimension *) XtCalloc ((unsigned int) n, |
214 | (unsigned int) sizeof(Dimension)); |
215 | *sizep = ((*listp) ? n : 0); |
216 | return; |
217 | } |
218 | if (n > *sizep) { |
219 | *listp = (Dimension *) XtRealloc((char *) *listp, |
220 | (unsigned int) (n*sizeof(Dimension))); |
221 | if (!*listp) { |
222 | *sizep = 0; |
223 | return; |
224 | } |
225 | for (i = *sizep, l = (*listp) + i; i < n; i++, l++) *l = 0; |
226 | *sizep = n; |
227 | } |
228 | return; |
229 | } |
230 | |
231 | static GC |
232 | get_tree_gc(TreeWidget w) |
233 | { |
234 | XtGCMask valuemask = GCBackground(1L<<3) | GCForeground(1L<<2); |
235 | XGCValues values; |
236 | |
237 | values.background = w->core.background_pixel; |
238 | values.foreground = w->tree.foreground; |
239 | if (w->tree.line_width != 0) { |
240 | valuemask |= GCLineWidth(1L<<4); |
241 | values.line_width = w->tree.line_width; |
242 | } |
243 | |
244 | return XtGetGC ((Widget) w, valuemask, &values); |
245 | } |
246 | |
247 | static void |
248 | insert_node(Widget parent, Widget node) |
249 | { |
250 | TreeConstraints pc; |
251 | TreeConstraints nc = TREE_CONSTRAINT(node)((TreeConstraints)((node)->core.constraints)); |
252 | int nindex; |
253 | |
254 | nc->tree.parent = parent; |
255 | |
256 | if (parent == NULL((void*)0)) return; |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | pc = TREE_CONSTRAINT(parent)((TreeConstraints)((parent)->core.constraints)); |
263 | nindex = pc->tree.n_children; |
264 | |
265 | if (pc->tree.n_children == pc->tree.max_children) { |
266 | pc->tree.max_children += (pc->tree.max_children / 2) + 2; |
267 | pc->tree.children = (WidgetList) XtRealloc ((char *)pc->tree.children, |
268 | (unsigned int) |
269 | ((pc->tree.max_children) * |
270 | sizeof(Widget))); |
271 | } |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | pc->tree.children[nindex] = node; |
278 | pc->tree.n_children++; |
279 | } |
280 | |
281 | static void |
282 | delete_node(Widget parent, Widget node) |
283 | { |
284 | TreeConstraints pc; |
285 | int pos, i; |
286 | |
287 | |
288 | |
289 | |
290 | if (!parent) return; |
291 | |
292 | pc = TREE_CONSTRAINT(parent)((TreeConstraints)((parent)->core.constraints)); |
293 | |
294 | |
295 | |
296 | |
297 | for (pos = 0; pos < pc->tree.n_children; pos++) |
298 | if (pc->tree.children[pos] == node) break; |
299 | |
300 | if (pos == pc->tree.n_children) return; |
301 | |
302 | |
303 | |
304 | |
305 | pc->tree.n_children--; |
306 | |
307 | |
308 | |
309 | |
310 | |
311 | for (i = pos; i < pc->tree.n_children; i++) |
312 | pc->tree.children[i] = pc->tree.children[i+1]; |
313 | |
314 | pc->tree.children[pc->tree.n_children] = NULL((void*)0); |
315 | } |
316 | |
317 | static void |
318 | check_gravity(TreeWidget tw, XtGravity grav) |
319 | { |
320 | switch (tw->tree.gravity) { |
321 | case WestGravity4: case NorthGravity2: case EastGravity6: case SouthGravity8: |
322 | break; |
323 | default: |
324 | tw->tree.gravity = grav; |
325 | break; |
326 | } |
327 | } |
328 | |
329 | |
330 | |
331 | |
332 | |
333 | |
334 | |
335 | |
336 | static void |
337 | XawTreeClassInitialize(void) |
338 | { |
339 | XawInitializeWidgetSet(); |
340 | XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRGravity((char*)&XtStrings[2042]), XmuCvtStringToGravity, NULL((void*)0), 0); |
341 | XtSetTypeConverter(XtRGravity((char*)&XtStrings[2042]), XtRString((char*)&XtStrings[1797]), XmuCvtGravityToString, |
342 | NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0)); |
343 | } |
344 | |
345 | |
346 | |
347 | static void |
348 | XawTreeInitialize(Widget grequest, Widget gnew, |
349 | ArgList args, Cardinal *num_args) |
350 | { |
351 | TreeWidget request = (TreeWidget) grequest, cnew = (TreeWidget) gnew; |
352 | Arg arglist[2]; |
353 | |
354 | |
355 | |
356 | |
357 | |
358 | if (request->core.width <= 0) cnew->core.width = 5; |
359 | if (request->core.height <= 0) cnew->core.height = 5; |
360 | |
361 | |
362 | |
363 | |
364 | if (request->tree.hpad == 0 && request->tree.vpad == 0) { |
365 | if (IsHorizontal (request)((request)->tree.gravity == 4 || (request)->tree.gravity == 6)) { |
366 | cnew->tree.hpad = TREE_HORIZONTAL_DEFAULT_SPACING20; |
367 | cnew->tree.vpad = TREE_VERTICAL_DEFAULT_SPACING6; |
368 | } else { |
369 | cnew->tree.hpad = TREE_VERTICAL_DEFAULT_SPACING6; |
370 | cnew->tree.vpad = TREE_HORIZONTAL_DEFAULT_SPACING20; |
371 | } |
372 | } |
373 | |
374 | |
375 | |
376 | |
377 | cnew->tree.gc = get_tree_gc (cnew); |
378 | |
379 | |
380 | |
381 | |
382 | cnew->tree.tree_root = (Widget) NULL((void*)0); |
383 | XtSetArg(arglist[0], XtNwidth, 1)((void)( (arglist[0]).name = (((char*)&XtStrings[872])), ( arglist[0]).value = (XtArgVal)(1) )); |
384 | XtSetArg(arglist[1], XtNheight, 1)((void)( (arglist[1]).name = (((char*)&XtStrings[234])), ( arglist[1]).value = (XtArgVal)(1) )); |
385 | cnew->tree.tree_root = XtCreateWidget ("root", widgetClass, gnew, |
386 | arglist,TWO((Cardinal)2)); |
387 | |
388 | |
389 | |
390 | |
391 | cnew->tree.largest = NULL((void*)0); |
392 | cnew->tree.n_largest = 0; |
393 | initialize_dimensions (&cnew->tree.largest, &cnew->tree.n_largest, |
394 | TREE_INITIAL_DEPTH10); |
395 | |
396 | |
397 | |
398 | |
399 | check_gravity (cnew, WestGravity4); |
400 | } |
401 | |
402 | |
403 | |
404 | static void |
405 | XawTreeConstraintInitialize(Widget request, Widget cnew, |
406 | ArgList args, Cardinal *num_args) |
407 | { |
408 | TreeConstraints tc = TREE_CONSTRAINT(cnew)((TreeConstraints)((cnew)->core.constraints)); |
409 | TreeWidget tw = (TreeWidget) cnew->core.parent; |
410 | |
411 | |
412 | |
413 | |
414 | tc->tree.n_children = 0; |
415 | tc->tree.max_children = 0; |
416 | tc->tree.children = (Widget *) NULL((void*)0); |
417 | tc->tree.x = tc->tree.y = 0; |
418 | tc->tree.bbsubwidth = 0; |
419 | tc->tree.bbsubheight = 0; |
420 | |
421 | |
422 | |
423 | |
424 | |
425 | |
426 | |
427 | if (tc->tree.parent) |
428 | insert_node (tc->tree.parent, cnew); |
429 | else if (tw->tree.tree_root) |
430 | insert_node (tw->tree.tree_root, cnew); |
431 | } |
432 | |
433 | |
434 | |
435 | static Boolean |
436 | XawTreeSetValues(Widget gcurrent, Widget grequest, Widget gnew, |
437 | ArgList args, Cardinal *num_args) |
438 | { |
439 | TreeWidget current = (TreeWidget) gcurrent, cnew = (TreeWidget) gnew; |
440 | Boolean redraw = FALSE0; |
441 | |
442 | |
443 | |
444 | |
445 | |
446 | if (cnew->tree.foreground != current->tree.foreground || |
447 | cnew->core.background_pixel != current->core.background_pixel || |
448 | cnew->tree.line_width != current->tree.line_width) { |
449 | XtReleaseGC (gnew, cnew->tree.gc); |
450 | cnew->tree.gc = get_tree_gc (cnew); |
451 | redraw = TRUE1; |
452 | } |
453 | |
454 | |
455 | |
456 | |
457 | |
458 | |
459 | if (cnew->tree.gravity != current->tree.gravity) { |
460 | check_gravity (cnew, current->tree.gravity); |
461 | } |
462 | |
463 | if (IsHorizontal(cnew)((cnew)->tree.gravity == 4 || (cnew)->tree.gravity == 6 ) != IsHorizontal(current)((current)->tree.gravity == 4 || (current)->tree.gravity == 6)) { |
464 | if (cnew->tree.vpad == current->tree.vpad && |
465 | cnew->tree.hpad == current->tree.hpad) { |
466 | cnew->tree.vpad = current->tree.hpad; |
467 | cnew->tree.hpad = current->tree.vpad; |
468 | } |
469 | } |
470 | |
471 | if (cnew->tree.vpad != current->tree.vpad || |
472 | cnew->tree.hpad != current->tree.hpad || |
473 | cnew->tree.gravity != current->tree.gravity) { |
474 | layout_tree (cnew, TRUE1); |
475 | redraw = FALSE0; |
476 | } |
477 | return redraw; |
478 | } |
479 | |
480 | |
481 | |
482 | static Boolean |
483 | XawTreeConstraintSetValues(Widget current, Widget request, Widget cnew, |
484 | ArgList args, Cardinal *num_args) |
485 | { |
486 | TreeConstraints newc = TREE_CONSTRAINT(cnew)((TreeConstraints)((cnew)->core.constraints)); |
487 | TreeConstraints curc = TREE_CONSTRAINT(current)((TreeConstraints)((current)->core.constraints)); |
488 | TreeWidget tw = (TreeWidget) cnew->core.parent; |
489 | |
490 | |
491 | |
492 | |
493 | |
494 | |
495 | if (curc->tree.parent != newc->tree.parent){ |
496 | if (curc->tree.parent) |
497 | delete_node (curc->tree.parent, cnew); |
498 | if (newc->tree.parent) |
499 | insert_node(newc->tree.parent, cnew); |
500 | |
501 | |
502 | |
503 | |
504 | |
505 | if (XtIsRealized((Widget)tw)(XtWindowOfObject((Widget)tw) != 0L)) |
506 | layout_tree (tw, FALSE0); |
507 | } |
508 | return False0; |
509 | } |
510 | |
511 | |
512 | static void |
513 | XawTreeConstraintDestroy(Widget w) |
514 | { |
515 | TreeConstraints tc = TREE_CONSTRAINT(w)((TreeConstraints)((w)->core.constraints)); |
516 | TreeWidget tw = (TreeWidget) XtParent(w)((w)->core.parent); |
517 | int i; |
518 | |
519 | |
520 | |
521 | |
522 | |
523 | |
524 | if (tw->tree.tree_root == w) { |
525 | if (tc->tree.n_children > 0) |
526 | tw->tree.tree_root = tc->tree.children[0]; |
527 | else |
528 | tw->tree.tree_root = NULL((void*)0); |
529 | } |
530 | |
531 | delete_node (tc->tree.parent, (Widget) w); |
532 | for (i = 0; i< tc->tree.n_children; i++) |
533 | insert_node (tc->tree.parent, tc->tree.children[i]); |
534 | |
535 | layout_tree ((TreeWidget) (w->core.parent), FALSE0); |
536 | } |
537 | |
538 | |
539 | static XtGeometryResult |
540 | XawTreeGeometryManager(Widget w, XtWidgetGeometry *request, |
541 | XtWidgetGeometry *reply) |
542 | { |
543 | |
544 | TreeWidget tw = (TreeWidget) w->core.parent; |
545 | |
546 | |
547 | |
548 | |
549 | if ((request->request_mode & CWX(1<<0) && request->x!=w->core.x) |
550 | ||(request->request_mode & CWY(1<<1) && request->y!=w->core.y)) |
551 | return (XtGeometryNo); |
552 | |
553 | |
554 | |
555 | |
556 | |
557 | if (request->request_mode & CWWidth(1<<2)) |
558 | w->core.width = request->width; |
559 | if (request->request_mode & CWHeight(1<<3)) |
560 | w->core.height = request->height; |
561 | if (request->request_mode & CWBorderWidth(1<<4)) |
562 | w->core.border_width = request->border_width; |
563 | |
564 | if (tw->tree.auto_reconfigure) layout_tree (tw, FALSE0); |
565 | return (XtGeometryYes); |
566 | } |
567 | |
568 | static void |
569 | XawTreeChangeManaged(Widget gw) |
570 | { |
571 | layout_tree ((TreeWidget) gw, FALSE0); |
572 | } |
573 | |
574 | |
575 | static void |
576 | XawTreeDestroy(Widget gw) |
577 | { |
578 | TreeWidget w = (TreeWidget) gw; |
579 | |
580 | XtReleaseGC (gw, w->tree.gc); |
581 | if (w->tree.largest) XtFree ((char *) w->tree.largest); |
582 | } |
583 | |
584 | |
585 | |
586 | static void |
587 | XawTreeRedisplay(Widget gw, XEvent *event, Region region) |
588 | { |
589 | TreeWidget tw = (TreeWidget) gw; |
590 | |
591 | #ifndef OLDXAW1 |
592 | if (tw->tree.display_list) |
593 | XawRunDisplayList(gw, tw->tree.display_list, event, region); |
594 | #endif |
595 | |
596 | |
597 | |
598 | |
599 | if (tw->core.visible) { |
600 | Cardinal i; |
601 | int j; |
602 | Display *dpy = XtDisplay (tw)(((tw)->core.screen)->display); |
603 | Window w = XtWindow (tw)((tw)->core.window); |
604 | |
605 | for (i = 0; i < tw->composite.num_children; i++) { |
606 | Widget child = tw->composite.children[i]; |
607 | TreeConstraints tc = TREE_CONSTRAINT(child)((TreeConstraints)((child)->core.constraints)); |
608 | |
609 | |
610 | |
611 | |
612 | if (child != tw->tree.tree_root && tc->tree.n_children) { |
613 | int srcx = child->core.x + child->core.border_width; |
614 | int srcy = child->core.y + child->core.border_width; |
615 | |
616 | switch (tw->tree.gravity) { |
617 | case WestGravity4: |
618 | srcx += child->core.width + child->core.border_width; |
619 | |
620 | case EastGravity6: |
621 | srcy += child->core.height / 2; |
622 | break; |
623 | |
624 | case NorthGravity2: |
625 | srcy += child->core.height + child->core.border_width; |
626 | |
627 | case SouthGravity8: |
628 | srcx += child->core.width / 2; |
629 | break; |
630 | } |
631 | |
632 | for (j = 0; j < tc->tree.n_children; j++) { |
633 | Widget k = tc->tree.children[j]; |
634 | GC gc = (tc->tree.gc ? tc->tree.gc : tw->tree.gc); |
635 | |
636 | switch (tw->tree.gravity) { |
637 | case WestGravity4: |
638 | |
639 | |
640 | |
641 | XDrawLine (dpy, w, gc, srcx, srcy, |
642 | (int) k->core.x, |
643 | (k->core.y + ((int) k->core.border_width) + |
644 | ((int) k->core.height) / 2)); |
645 | break; |
646 | |
647 | case NorthGravity2: |
648 | |
649 | |
650 | |
651 | XDrawLine (dpy, w, gc, srcx, srcy, |
652 | (k->core.x + ((int) k->core.border_width) + |
653 | ((int) k->core.width) / 2), |
654 | (int) k->core.y); |
655 | break; |
656 | |
657 | case EastGravity6: |
658 | |
659 | |
660 | |
661 | XDrawLine (dpy, w, gc, srcx, srcy, |
662 | (k->core.x + |
663 | (((int) k->core.border_width) << 1) + |
664 | (int) k->core.width), |
665 | (k->core.y + ((int) k->core.border_width) + |
666 | ((int) k->core.height) / 2)); |
667 | break; |
668 | |
669 | case SouthGravity8: |
670 | |
671 | |
672 | |
673 | XDrawLine (dpy, w, gc, srcx, srcy, |
674 | (k->core.x + ((int) k->core.border_width) + |
675 | ((int) k->core.width) / 2), |
676 | (k->core.y + |
677 | (((int) k->core.border_width) << 1) + |
678 | (int) k->core.height)); |
679 | break; |
680 | } |
681 | } |
682 | } |
683 | } |
684 | } |
685 | } |
686 | |
687 | static XtGeometryResult |
688 | XawTreeQueryGeometry(Widget w, XtWidgetGeometry *intended, |
689 | XtWidgetGeometry *preferred) |
690 | { |
691 | TreeWidget tw = (TreeWidget) w; |
692 | |
693 | preferred->request_mode = (CWWidth(1<<2) | CWHeight(1<<3)); |
694 | preferred->width = tw->tree.maxwidth; |
695 | preferred->height = tw->tree.maxheight; |
696 | |
697 | if (((intended->request_mode & (CWWidth(1<<2) | CWHeight(1<<3))) == |
698 | (CWWidth(1<<2) | CWHeight(1<<3))) && |
699 | intended->width == preferred->width && |
700 | intended->height == preferred->height) |
701 | return XtGeometryYes; |
702 | else if (preferred->width == w->core.width && |
703 | preferred->height == w->core.height) |
704 | return XtGeometryNo; |
705 | else |
706 | return XtGeometryAlmost; |
707 | } |
708 | |
709 | |
710 | |
711 | |
712 | |
713 | |
714 | |
715 | |
716 | |
717 | |
718 | |
719 | |
720 | |
721 | static void |
722 | compute_bounding_box_subtree(TreeWidget tree, Widget w, int depth) |
723 | { |
724 | TreeConstraints tc = TREE_CONSTRAINT(w)((TreeConstraints)((w)->core.constraints)); |
725 | int i; |
726 | Boolint horiz = IsHorizontal (tree)((tree)->tree.gravity == 4 || (tree)->tree.gravity == 6 ); |
727 | Dimension newwidth, newheight; |
728 | Dimension bw2 = w->core.border_width * 2; |
729 | |
730 | |
731 | |
732 | |
733 | if (depth >= tree->tree.n_largest) { |
734 | initialize_dimensions (&tree->tree.largest, |
735 | &tree->tree.n_largest, depth + 1); |
736 | } |
737 | newwidth = ((horiz ? w->core.width : w->core.height) + bw2); |
738 | if (tree->tree.largest[depth] < newwidth) |
739 | tree->tree.largest[depth] = newwidth; |
740 | |
741 | |
742 | |
743 | |
744 | |
745 | tc->tree.bbwidth = w->core.width + bw2; |
746 | tc->tree.bbheight = w->core.height + bw2; |
747 | |
748 | if (tc->tree.n_children == 0) return; |
749 | |
750 | |
751 | |
752 | |
753 | |
754 | |
755 | newwidth = 0; |
756 | newheight = 0; |
757 | for (i = 0; i < tc->tree.n_children; i++) { |
758 | Widget child = tc->tree.children[i]; |
759 | TreeConstraints cc = TREE_CONSTRAINT(child)((TreeConstraints)((child)->core.constraints)); |
760 | |
761 | compute_bounding_box_subtree (tree, child, depth + 1); |
762 | |
763 | if (horiz) { |
764 | if (newwidth < cc->tree.bbwidth) newwidth = cc->tree.bbwidth; |
765 | newheight += tree->tree.vpad + cc->tree.bbheight; |
766 | } else { |
767 | if (newheight < cc->tree.bbheight) newheight = cc->tree.bbheight; |
768 | newwidth += tree->tree.hpad + cc->tree.bbwidth; |
769 | } |
770 | } |
771 | |
772 | |
773 | tc->tree.bbsubwidth = newwidth; |
774 | tc->tree.bbsubheight = newheight; |
775 | |
776 | |
777 | |
778 | |
779 | |
780 | if (horiz) { |
781 | tc->tree.bbwidth += tree->tree.hpad + newwidth; |
782 | newheight -= tree->tree.vpad; |
783 | if (newheight > tc->tree.bbheight) tc->tree.bbheight = newheight; |
784 | } else { |
785 | tc->tree.bbheight += tree->tree.vpad + newheight; |
786 | newwidth -= tree->tree.hpad; |
787 | if (newwidth > tc->tree.bbwidth) tc->tree.bbwidth = newwidth; |
788 | } |
789 | } |
790 | |
791 | |
792 | static void |
793 | set_positions(TreeWidget tw, Widget w, int level) |
794 | { |
795 | int i; |
796 | |
797 | if (w) { |
798 | TreeConstraints tc = TREE_CONSTRAINT(w)((TreeConstraints)((w)->core.constraints)); |
799 | |
800 | if (level > 0) { |
801 | |
802 | |
803 | |
804 | switch (tw->tree.gravity) { |
805 | case EastGravity6: |
806 | tc->tree.x = (((Position) tw->tree.maxwidth) - |
807 | ((Position) w->core.width) - tc->tree.x); |
808 | break; |
809 | |
810 | case SouthGravity8: |
811 | tc->tree.y = (((Position) tw->tree.maxheight) - |
812 | ((Position) w->core.height) - tc->tree.y); |
813 | break; |
814 | } |
815 | |
816 | |
817 | |
818 | |
819 | XtMoveWidget (w, tc->tree.x, tc->tree.y); |
820 | } |
821 | |
822 | |
823 | |
824 | |
825 | for (i = 0; i < tc->tree.n_children; i++) |
826 | set_positions (tw, tc->tree.children[i], level + 1); |
827 | } |
828 | } |
829 | |
830 | |
831 | static void |
832 | arrange_subtree(TreeWidget tree, Widget w, int depth, int x, int y) |
833 | { |
834 | TreeConstraints tc = TREE_CONSTRAINT(w)((TreeConstraints)((w)->core.constraints)); |
835 | TreeConstraints firstcc, lastcc; |
836 | int i; |
837 | int newx, newy; |
838 | Boolint horiz = IsHorizontal (tree)((tree)->tree.gravity == 4 || (tree)->tree.gravity == 6 ); |
839 | Widget child = NULL((void*)0); |
840 | Dimension tmp; |
841 | Dimension bw2 = w->core.border_width * 2; |
842 | Boolint relayout = True1; |
843 | |
844 | |
845 | |
846 | |
847 | |
848 | tc->tree.x = x; |
849 | tc->tree.y = y; |
850 | |
851 | if (horiz) { |
| |
852 | int myh = (w->core.height + bw2); |
853 | |
854 | if (myh > (int)tc->tree.bbsubheight) { |
| |
855 | y += (myh - (int)tc->tree.bbsubheight) / 2; |
856 | relayout = False0; |
857 | } |
858 | } else { |
859 | int myw = (w->core.width + bw2); |
860 | |
861 | if (myw > (int)tc->tree.bbsubwidth) { |
862 | x += (myw - (int)tc->tree.bbsubwidth) / 2; |
863 | relayout = False0; |
864 | } |
865 | } |
866 | |
867 | if ((tmp = ((Dimension) x) + tc->tree.bbwidth) > tree->tree.maxwidth) |
| |
868 | tree->tree.maxwidth = tmp; |
869 | if ((tmp = ((Dimension) y) + tc->tree.bbheight) > tree->tree.maxheight) |
| |
870 | tree->tree.maxheight = tmp; |
871 | |
872 | if (tc->tree.n_children == 0) return; |
| |
873 | |
874 | |
875 | |
876 | |
877 | |
878 | |
879 | if (horiz) { |
| |
880 | newx = x + tree->tree.largest[depth]; |
881 | if (depth > 0) newx += tree->tree.hpad; |
| 7 | Assuming 'depth' is <= 0 |
|
| |
882 | newy = y; |
883 | } else { |
884 | newx = x; |
885 | newy = y + tree->tree.largest[depth]; |
886 | if (depth > 0) newy += tree->tree.vpad; |
887 | } |
888 | |
889 | for (i = 0; i < tc->tree.n_children; i++) { |
| 9 | Loop condition is false. Execution continues on line 906 |
|
890 | TreeConstraints cc; |
891 | |
892 | child = tc->tree.children[i]; |
893 | cc = TREE_CONSTRAINT(child)((TreeConstraints)((child)->core.constraints)); |
894 | |
895 | arrange_subtree (tree, child, depth + 1, newx, newy); |
896 | if (horiz) { |
897 | newy += tree->tree.vpad + cc->tree.bbheight; |
898 | } else { |
899 | newx += tree->tree.hpad + cc->tree.bbwidth; |
900 | } |
901 | } |
902 | |
903 | |
904 | |
905 | |
906 | if (relayout) { |
| |
907 | Position adjusted; |
908 | firstcc = TREE_CONSTRAINT (tc->tree.children[0])((TreeConstraints)((tc->tree.children[0])->core.constraints )); |
909 | lastcc = TREE_CONSTRAINT (child)((TreeConstraints)((child)->core.constraints)); |
| 11 | Within the expansion of the macro 'TREE_CONSTRAINT':
|
a | Dereference of null pointer |
|
910 | |
911 | |
912 | |
913 | |
914 | |
915 | if (horiz) { |
916 | tc->tree.x = x; |
917 | adjusted = firstcc->tree.y + |
918 | ((lastcc->tree.y + (Position) child->core.height + |
919 | (Position) child->core.border_width * 2 - |
920 | firstcc->tree.y - (Position) w->core.height - |
921 | (Position) w->core.border_width * 2 + 1) / 2); |
922 | if (adjusted > tc->tree.y) tc->tree.y = adjusted; |
923 | } else { |
924 | adjusted = firstcc->tree.x + |
925 | ((lastcc->tree.x + (Position) child->core.width + |
926 | (Position) child->core.border_width * 2 - |
927 | firstcc->tree.x - (Position) w->core.width - |
928 | (Position) w->core.border_width * 2 + 1) / 2); |
929 | if (adjusted > tc->tree.x) tc->tree.x = adjusted; |
930 | tc->tree.y = y; |
931 | } |
932 | } |
933 | } |
934 | |
935 | static void |
936 | set_tree_size(TreeWidget tw, Boolint insetvalues, |
937 | unsigned int width, unsigned int height) |
938 | { |
939 | if (insetvalues) { |
940 | tw->core.width = width; |
941 | tw->core.height = height; |
942 | } else { |
943 | Dimension replyWidth = 0, replyHeight = 0; |
944 | XtGeometryResult result = XtMakeResizeRequest ((Widget) tw, |
945 | width, height, |
946 | &replyWidth, |
947 | &replyHeight); |
948 | |
949 | |
950 | |
951 | if (result == XtGeometryAlmost) |
952 | XtMakeResizeRequest ((Widget) tw, replyWidth, replyHeight, |
953 | (Dimension *) NULL((void*)0), (Dimension *) NULL((void*)0)); |
954 | } |
955 | return; |
956 | } |
957 | |
958 | static void |
959 | layout_tree(TreeWidget tw, Boolint insetvalues) |
960 | { |
961 | int i; |
962 | Dimension *dp; |
963 | |
964 | |
965 | |
966 | |
967 | |
968 | |
969 | |
970 | if (tw->tree.tree_root == NULL((void*)0)) |
971 | return; |
972 | |
973 | tw->tree.maxwidth = tw->tree.maxheight = 0; |
974 | for (i = 0, dp = tw->tree.largest; i < tw->tree.n_largest; i++, dp++) |
975 | *dp = 0; |
976 | initialize_dimensions (&tw->tree.largest, &tw->tree.n_largest, |
977 | tw->tree.n_largest); |
978 | compute_bounding_box_subtree (tw, tw->tree.tree_root, 0); |
979 | |
980 | |
981 | |
982 | |
983 | |
984 | |
985 | arrange_subtree (tw, tw->tree.tree_root, 0, 0, 0); |
986 | |
987 | |
988 | |
989 | |
990 | set_tree_size (tw, insetvalues, tw->tree.maxwidth, tw->tree.maxheight); |
991 | set_positions (tw, tw->tree.tree_root, 0); |
992 | |
993 | |
994 | |
995 | |
996 | if (XtIsRealized ((Widget) tw)(XtWindowOfObject((Widget) tw) != 0L)) { |
997 | XClearArea (XtDisplay(tw)(((tw)->core.screen)->display), XtWindow((Widget)tw)(((Widget)tw)->core.window), 0, 0, 0, 0, True1); |
998 | } |
999 | } |
1000 | |
1001 | |
1002 | |
1003 | |
1004 | |
1005 | |
1006 | |
1007 | |
1008 | |
1009 | void |
1010 | XawTreeForceLayout(Widget tree) |
1011 | { |
1012 | layout_tree ((TreeWidget) tree, FALSE0); |
1013 | } |
1014 | |