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 | #ifdef HAVE_CONFIG_H1 |
50 | #include "config.h" |
51 | #endif |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | #include <X11/IntrinsicP.h> |
59 | #include <X11/StringDefs.h> |
60 | #include <X11/Xmu/Misc.h> |
61 | #include <X11/Xaw3d/XawInit.h> |
62 | #include <X11/Xaw3d/BoxP.h> |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | static XtResource resources[] = { |
71 | { XtNhSpace((char*)&XtStrings[251]), XtCHSpace((char*)&XtStrings[1058]), XtRDimension((char*)&XtStrings[1618]), sizeof(Dimension), |
72 | XtOffsetOf(BoxRec, box.h_space)__builtin_offsetof(BoxRec, box.h_space), |
73 | XtRImmediate((char*)&XtStrings[1695]), (XtPointer)4 }, |
74 | { XtNvSpace((char*)&XtStrings[865]), XtCVSpace((char*)&XtStrings[1503]), XtRDimension((char*)&XtStrings[1618]), sizeof(Dimension), |
75 | XtOffsetOf(BoxRec, box.v_space)__builtin_offsetof(BoxRec, box.v_space), |
76 | XtRImmediate((char*)&XtStrings[1695]), (XtPointer)4 }, |
77 | { XtNorientation((char*)&XtStrings[505]), XtCOrientation((char*)&XtStrings[1206]), XtROrientation((char*)&XtStrings[1742]), sizeof(XtOrientation), |
78 | XtOffsetOf(BoxRec, box.orientation)__builtin_offsetof(BoxRec, box.orientation), |
79 | XtRImmediate((char*)&XtStrings[1695]), (XtPointer)XtorientVertical }, |
80 | }; |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
88 | static void ClassInitialize(void); |
89 | static void Initialize(Widget, Widget, ArgList, Cardinal *); |
90 | static void Realize(Widget, Mask *, XSetWindowAttributes *); |
91 | static void Resize(Widget); |
92 | static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *); |
93 | static XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *, XtWidgetGeometry *); |
94 | static void ChangeManaged(Widget); |
95 | static XtGeometryResult PreferredSize(Widget, XtWidgetGeometry *, XtWidgetGeometry *); |
96 | |
97 | BoxClassRec boxClassRec = { |
98 | { |
99 | |
100 | (WidgetClass) &compositeClassRec, |
101 | "Box", |
102 | sizeof(BoxRec), |
103 | ClassInitialize, |
104 | NULL((void*)0), |
105 | FALSE0, |
106 | Initialize, |
107 | NULL((void*)0), |
108 | Realize, |
109 | NULL((void*)0), |
110 | 0, |
111 | resources, |
112 | XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), |
113 | NULLQUARK((XrmQuark) 0), |
114 | TRUE1, |
115 | TRUE1, |
116 | TRUE1, |
117 | FALSE0, |
118 | NULL((void*)0), |
119 | Resize, |
120 | NULL((void*)0), |
121 | SetValues, |
122 | NULL((void*)0), |
123 | XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit), |
124 | NULL((void*)0), |
125 | NULL((void*)0), |
126 | XtVersion(11 * 1000 + 6), |
127 | NULL((void*)0), |
128 | NULL((void*)0), |
129 | PreferredSize, |
130 | XtInheritDisplayAccelerator((XtStringProc) _XtInherit), |
131 | NULL((void*)0) |
132 | },{ |
133 | |
134 | GeometryManager, |
135 | ChangeManaged, |
136 | XtInheritInsertChild((XtWidgetProc) _XtInherit), |
137 | XtInheritDeleteChild((XtWidgetProc) _XtInherit), |
138 | NULL((void*)0) |
139 | },{ |
140 | |
141 | 0, |
142 | } |
143 | }; |
144 | |
145 | WidgetClass boxWidgetClass = (WidgetClass)&boxClassRec; |
146 | |
147 | |
148 | |
149 | |
150 | |
151 | |
152 | |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | static void |
162 | DoLayout(BoxWidget bbw, Dimension width, Dimension height, |
163 | Dimension *reply_width, Dimension *reply_height, Boolean position) |
164 | { |
165 | Boolean vbox = (bbw->box.orientation == XtorientVertical); |
166 | Cardinal i; |
167 | Dimension w, h; |
168 | Dimension lw, lh; |
169 | Dimension bw, bh; |
170 | Dimension h_space; |
171 | Widget widget; |
172 | int num_mapped_children = 0; |
173 | |
174 | |
175 | h_space = bbw->box.h_space; |
176 | |
177 | w = 0; |
178 | for (i = 0; i < bbw->composite.num_children; i++) { |
179 | if ( bbw->composite.children[i]->core.width > w ) |
180 | w = bbw->composite.children[i]->core.width; |
181 | } |
182 | w += h_space; |
183 | if ( w > width ) width = w; |
184 | h = bbw->box.v_space; |
185 | |
186 | |
187 | lh = 0; |
188 | lw = h_space; |
189 | |
190 | for (i = 0; i < bbw->composite.num_children; i++) { |
191 | widget = bbw->composite.children[i]; |
192 | if (widget->core.managed) { |
193 | if (widget->core.mapped_when_managed) num_mapped_children++; |
194 | |
195 | bw = widget->core.width + 2*widget->core.border_width + h_space; |
196 | if ((Dimension)(lw + bw) > width) { |
197 | if (lw > h_space) { |
198 | |
199 | |
200 | |
201 | AssignMax(w, lw){if ((lw) > (w)) w = (lw);}; |
202 | if (vbox) { |
203 | h += lh + bbw->box.v_space; |
204 | lh = 0; |
205 | lw = h_space; |
206 | } |
207 | } |
208 | else if (!position) { |
209 | |
210 | DoLayout(bbw, lw + bw, height, reply_width, |
211 | reply_height, position); |
212 | return; |
213 | } |
214 | } |
215 | if (position && (lw != (Dimension)widget->core.x || h != (Dimension)widget->core.y)) { |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | if (XtIsRealized(widget)(XtWindowOfObject(widget) != 0L) && widget->core.mapped_when_managed) |
229 | XUnmapWindow( XtDisplay(widget)(((widget)->core.screen)->display), XtWindow(widget)((widget)->core.window) ); |
230 | XtMoveWidget(widget, (int)lw, (int)h); |
231 | } |
232 | lw += bw; |
233 | bh = widget->core.height + 2*widget->core.border_width; |
234 | AssignMax(lh, bh){if ((bh) > (lh)) lh = (bh);}; |
235 | } |
236 | } |
237 | |
238 | if (!vbox && width && lw > width && lh < height) { |
239 | |
240 | Dimension sw = lw, sh = lh; |
241 | Dimension width_needed = 0; |
242 | XtOrientation orientation = bbw->box.orientation; |
243 | bbw->box.orientation = XtorientVertical; |
244 | while (sh < height && sw > width) { |
245 | width_needed = sw; |
246 | DoLayout(bbw, sw-1, height, &sw, &sh, False0); |
247 | } |
248 | if (sh < height) width_needed = sw; |
249 | if (width_needed != lw) { |
250 | DoLayout(bbw,width_needed,height,reply_width,reply_height,position); |
251 | bbw->box.orientation = orientation; |
252 | return; |
253 | } |
254 | bbw->box.orientation = orientation; |
255 | } |
256 | if ( vbox && ( ( width < w ) || ( width < lw ) ) ) { |
257 | AssignMax(w, lw){if ((lw) > (w)) w = (lw);}; |
258 | DoLayout( bbw, w, height, reply_width, reply_height, position ); |
259 | return; |
260 | } |
261 | if (position && XtIsRealized((Widget)bbw)(XtWindowOfObject((Widget)bbw) != 0L)) { |
262 | if (bbw->composite.num_children == num_mapped_children) |
263 | XMapSubwindows( XtDisplay((Widget)bbw)((((Widget)bbw)->core.screen)->display), XtWindow((Widget)bbw)(((Widget)bbw)->core.window) ); |
264 | else { |
265 | int j = bbw->composite.num_children; |
266 | Widget *childP = bbw->composite.children; |
267 | for (; j > 0; childP++, j--) |
268 | if (XtIsRealized(*childP)(XtWindowOfObject(*childP) != 0L) && XtIsManaged(*childP) && |
269 | (*childP)->core.mapped_when_managed) |
270 | XtMapWidget(*childP)XMapWindow((((*childP)->core.screen)->display), ((*childP )->core.window)); |
271 | } |
272 | } |
273 | |
274 | |
275 | if (lw > h_space) { |
276 | AssignMax(w, lw){if ((lw) > (w)) w = (lw);}; |
277 | h += lh + bbw->box.v_space; |
278 | } |
279 | |
280 | *reply_width = Max(w, 1)(((w) > (1)) ? (w) : (1)); |
281 | *reply_height = Max(h, 1)(((h) > (1)) ? (h) : (1)); |
282 | } |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | static XtGeometryResult |
291 | PreferredSize(Widget widget, XtWidgetGeometry *constraint, XtWidgetGeometry *preferred) |
292 | { |
293 | BoxWidget w = (BoxWidget)widget; |
294 | Dimension width ; |
295 | Dimension preferred_width = w->box.preferred_width; |
296 | Dimension preferred_height = w->box.preferred_height; |
297 | |
298 | constraint->request_mode &= CWWidth(1<<2) | CWHeight(1<<3); |
299 | |
300 | if (constraint->request_mode == 0) |
| |
301 | |
302 | return XtGeometryYes; |
303 | |
304 | if (constraint->request_mode == w->box.last_query_mode && |
305 | (!(constraint->request_mode & CWWidth(1<<2)) || |
306 | constraint->width == w->box.last_query_width) && |
307 | (!(constraint->request_mode & CWHeight(1<<3)) || |
308 | constraint->height == w->box.last_query_height)) { |
309 | |
310 | preferred->request_mode = CWWidth(1<<2) | CWHeight(1<<3); |
311 | preferred->width = preferred_width; |
312 | preferred->height = preferred_height; |
313 | if (constraint->request_mode == (CWWidth(1<<2) | CWHeight(1<<3)) && |
314 | constraint->width == preferred_width && |
315 | constraint->height == preferred_height) |
316 | return XtGeometryYes; |
317 | else |
318 | return XtGeometryAlmost; |
319 | } |
320 | |
321 | |
322 | |
323 | |
324 | |
325 | |
326 | w->box.last_query_mode = constraint->request_mode; |
327 | w->box.last_query_width = constraint->width; |
| 6 | | Assigned value is garbage or undefined |
|
328 | w->box.last_query_height= constraint->height; |
329 | |
330 | if (constraint->request_mode & CWWidth(1<<2)) |
331 | width = constraint->width; |
332 | else { |
333 | |
334 | width = 0; |
335 | constraint->width = 65535; |
336 | } |
337 | |
338 | |
339 | |
340 | |
341 | |
342 | DoLayout(w, width, (Dimension)0, |
343 | &preferred_width, &preferred_height, FALSE0); |
344 | |
345 | if (constraint->request_mode & CWHeight(1<<3) && |
346 | preferred_height > constraint->height) { |
347 | |
348 | if (preferred_width > constraint->width) { |
349 | |
350 | } |
351 | else { |
352 | width = preferred_width; |
353 | do { |
354 | if (width > (constraint->width >> 1)) |
355 | width = constraint->width; |
356 | else |
357 | width <<= 1; |
358 | DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE0); |
359 | } while (preferred_height > constraint->height |
360 | && width < constraint->width); |
361 | if (width != constraint->width) { |
362 | do { |
363 | width = preferred_width; |
364 | DoLayout(w, preferred_width-1, 0, |
365 | &preferred_width, &preferred_height, FALSE0); |
366 | } while (preferred_height < constraint->height); |
367 | |
368 | DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE0); |
369 | } |
370 | } |
371 | } |
372 | |
373 | preferred->request_mode = CWWidth(1<<2) | CWHeight(1<<3); |
374 | preferred->width = w->box.preferred_width = preferred_width; |
375 | preferred->height = w->box.preferred_height = preferred_height; |
376 | |
377 | if (constraint->request_mode == (CWWidth(1<<2)|CWHeight(1<<3)) |
378 | && constraint->width == preferred_width |
379 | && constraint->height == preferred_height) |
380 | return XtGeometryYes; |
381 | else |
382 | return XtGeometryAlmost; |
383 | |
384 | } |
385 | |
386 | |
387 | |
388 | |
389 | |
390 | |
391 | |
392 | static void |
393 | Resize(Widget w) |
394 | { |
395 | Dimension junk; |
396 | |
397 | DoLayout((BoxWidget)w, w->core.width, w->core.height, &junk, &junk, TRUE1); |
398 | |
399 | } |
400 | |
401 | |
402 | |
403 | |
404 | |
405 | |
406 | |
407 | |
408 | |
409 | |
410 | static Boolean |
411 | TryNewLayout(BoxWidget bbw) |
412 | { |
413 | Dimension preferred_width, preferred_height; |
414 | Dimension proposed_width, proposed_height; |
415 | int iterations; |
416 | |
417 | DoLayout( bbw, bbw->core.width, bbw->core.height, |
418 | &preferred_width, &preferred_height, FALSE0 ); |
419 | |
420 | |
421 | |
422 | |
423 | |
424 | if ((bbw->core.width == preferred_width) && |
425 | (bbw->core.height == preferred_height)) { |
426 | |
427 | return (TRUE1); |
428 | } |
429 | |
430 | |
431 | iterations = 0; |
432 | proposed_width = preferred_width; |
433 | proposed_height = preferred_height; |
434 | do { |
435 | switch (XtMakeResizeRequest((Widget)bbw,proposed_width,proposed_height, |
| 2 | | Control jumps to 'case XtGeometryAlmost:' at line 452 | |
|
436 | &proposed_width, &proposed_height)) |
437 | { |
438 | case XtGeometryYes: |
439 | return (TRUE1); |
440 | |
441 | case XtGeometryNo: |
442 | if (iterations > 0) |
443 | |
444 | DoLayout( bbw, bbw->core.width, bbw->core.height, |
445 | &preferred_width, &preferred_height, FALSE0 ); |
446 | if ((preferred_width <= bbw->core.width) && |
447 | (preferred_height <= bbw->core.height)) |
448 | return (TRUE1); |
449 | else |
450 | return (FALSE0); |
451 | |
452 | case XtGeometryAlmost: |
453 | if (proposed_height >= preferred_height && |
454 | proposed_width >= preferred_width) { |
455 | |
456 | |
457 | |
458 | |
459 | |
460 | |
461 | |
462 | |
463 | (void) XtMakeResizeRequest( (Widget)bbw, |
464 | proposed_width, proposed_height, |
465 | &proposed_width, &proposed_height); |
466 | return(TRUE1); |
467 | } |
468 | else if (proposed_width != preferred_width) { |
| |
469 | |
470 | DoLayout(bbw, proposed_width, 0, |
471 | &preferred_width, &preferred_height, FALSE0); |
472 | proposed_height = preferred_height; |
473 | } |
474 | else { |
475 | XtWidgetGeometry constraints, reply; |
476 | constraints.request_mode = CWHeight(1<<3); |
477 | constraints.height = proposed_height; |
478 | (void)PreferredSize((Widget)bbw, &constraints, &reply); |
| |
479 | proposed_width = preferred_width; |
480 | } |
481 | break; |
482 | |
483 | case XtGeometryDone: |
484 | default: |
485 | break; |
486 | } |
487 | iterations++; |
488 | } while (iterations < 10); |
489 | return (FALSE0); |
490 | } |
491 | |
492 | |
493 | |
494 | |
495 | |
496 | |
497 | |
498 | |
499 | |
500 | |
501 | static XtGeometryResult |
502 | GeometryManager(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply) |
503 | { |
504 | Dimension width, height, borderWidth; |
505 | BoxWidget bbw; |
506 | |
507 | |
508 | if ((request->request_mode & CWX(1<<0) && request->x != w->core.x) || |
509 | (request->request_mode & CWY(1<<1) && request->y != w->core.y)) |
510 | return (XtGeometryNo); |
511 | |
512 | |
513 | if (request->request_mode & (CWWidth(1<<2) | CWHeight(1<<3) | CWBorderWidth(1<<4))) { |
514 | |
515 | |
516 | if ((request->request_mode & CWWidth(1<<2)) == 0) |
517 | request->width = w->core.width; |
518 | if ((request->request_mode & CWHeight(1<<3)) == 0) |
519 | request->height = w->core.height; |
520 | if ((request->request_mode & CWBorderWidth(1<<4)) == 0) |
521 | request->border_width = w->core.border_width; |
522 | |
523 | |
524 | width = w->core.width; |
525 | height = w->core.height; |
526 | borderWidth = w->core.border_width; |
527 | w->core.width = request->width; |
528 | w->core.height = request->height; |
529 | w->core.border_width = request->border_width; |
530 | |
531 | |
532 | |
533 | |
534 | |
535 | bbw = (BoxWidget) w->core.parent; |
536 | |
537 | |
538 | |
539 | |
540 | |
541 | |
542 | |
543 | |
544 | |
545 | if (TryNewLayout(bbw)) { |
546 | |
547 | (*XtClass((Widget)bbw)(((Widget)bbw)->core.widget_class)->core_class.resize)((Widget)bbw); |
548 | return (XtGeometryYes); |
549 | } else { |
550 | |
551 | w->core.width = width; |
552 | w->core.height = height; |
553 | w->core.border_width = borderWidth; |
554 | return (XtGeometryNo); |
555 | } |
556 | }; |
557 | |
558 | |
559 | return (XtGeometryYes); |
560 | } |
561 | |
562 | static void |
563 | ChangeManaged(Widget w) |
564 | { |
565 | |
566 | (void) TryNewLayout((BoxWidget)w); |
| |
567 | Resize(w); |
568 | } |
569 | |
570 | static void |
571 | ClassInitialize(void) |
572 | { |
573 | XawInitializeWidgetSet(); |
574 | XtAddConverter( XtRString((char*)&XtStrings[1797]), XtROrientation((char*)&XtStrings[1742]), XmuCvtStringToOrientation, |
575 | (XtConvertArgList)NULL((void*)0), (Cardinal)0 ); |
576 | } |
577 | |
578 | |
579 | static void |
580 | Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args) |
581 | { |
582 | BoxWidget newbbw = (BoxWidget)new; |
583 | |
584 | newbbw->box.last_query_mode = CWWidth(1<<2) | CWHeight(1<<3); |
585 | newbbw->box.last_query_width = newbbw->box.last_query_height = 0; |
586 | newbbw->box.preferred_width = Max(newbbw->box.h_space, 1)(((newbbw->box.h_space) > (1)) ? (newbbw->box.h_space ) : (1)); |
587 | newbbw->box.preferred_height = Max(newbbw->box.v_space, 1)(((newbbw->box.v_space) > (1)) ? (newbbw->box.v_space ) : (1)); |
588 | |
589 | if (newbbw->core.width == 0) |
590 | newbbw->core.width = newbbw->box.preferred_width; |
591 | |
592 | if (newbbw->core.height == 0) |
593 | newbbw->core.height = newbbw->box.preferred_height; |
594 | |
595 | } |
596 | |
597 | static void |
598 | Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes) |
599 | { |
600 | attributes->bit_gravity = NorthWestGravity1; |
601 | *valueMask |= CWBitGravity(1L<<4); |
602 | |
603 | XtCreateWindow( w, (unsigned)InputOutput1, (Visual *)CopyFromParent0L, |
604 | *valueMask, attributes); |
605 | } |
606 | |
607 | |
608 | static Boolean |
609 | SetValues(Widget current, Widget request, Widget new, ArgList args, Cardinal *num_args) |
610 | { |
611 | |
612 | |
613 | return False0; |
614 | } |