rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1Form.c
blob910f998f18dde172de22f344f331b06faee6852e
1 #ifndef lint
2 static char Xrcsid[] = "$XConsortium: Form.c,v 1.34 89/12/13 13:51:07 kit Exp $";
3 #endif /* lint */
6 /***********************************************************
7 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
8 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
10 All Rights Reserved
12 Permission to use, copy, modify, and distribute this software and its
13 documentation for any purpose and without fee is hereby granted,
14 provided that the above copyright notice appear in all copies and that
15 both that copyright notice and this permission notice appear in
16 supporting documentation, and that the names of Digital or MIT not be
17 used in advertising or publicity pertaining to distribution of the
18 software without specific, written prior permission.
20 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
21 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 SOFTWARE.
28 ******************************************************************/
30 #include <X11/IntrinsicP.h>
31 #include <X11/StringDefs.h>
32 #include <X11/Xmu/Converters.h>
33 #include <X11/Xmu/CharSet.h>
34 #include <./Xaw3_1XawInit.h>
35 #include <./Xaw3_1FormP.h>
37 /* Private Definitions */
39 static int default_value = -99999;
41 #define Offset(field) XtOffset(FormWidget, form.field)
42 static XtResource resources[] = {
43 {XtNdefaultDistance, XtCThickness, XtRInt, sizeof(int),
44 Offset(default_spacing), XtRImmediate, (caddr_t)4}
46 #undef Offset
48 static XtEdgeType defEdge = XtRubber;
50 #define Offset(field) XtOffset(FormConstraints, form.field)
51 static XtResource formConstraintResources[] = {
52 {XtNtop, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
53 Offset(top), XtREdgeType, (XtPointer)&defEdge},
54 {XtNbottom, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
55 Offset(bottom), XtREdgeType, (XtPointer)&defEdge},
56 {XtNleft, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
57 Offset(left), XtREdgeType, (XtPointer)&defEdge},
58 {XtNright, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
59 Offset(right), XtREdgeType, (XtPointer)&defEdge},
60 {XtNhorizDistance, XtCThickness, XtRInt, sizeof(int),
61 Offset(dx), XtRInt, (XtPointer) &default_value},
62 {XtNfromHoriz, XtCWidget, XtRWidget, sizeof(Widget),
63 Offset(horiz_base), XtRWidget, (XtPointer)NULL},
64 {XtNvertDistance, XtCThickness, XtRInt, sizeof(int),
65 Offset(dy), XtRInt, (XtPointer) &default_value},
66 {XtNfromVert, XtCWidget, XtRWidget, sizeof(Widget),
67 Offset(vert_base), XtRWidget, (XtPointer)NULL},
68 {XtNresizable, XtCBoolean, XtRBoolean, sizeof(Boolean),
69 Offset(allow_resize), XtRImmediate, (XtPointer) FALSE},
71 #undef Offset
73 static void ClassInitialize(), ClassPartInitialize(), Initialize(), Resize();
74 static void ConstraintInitialize();
75 static Boolean SetValues(), ConstraintSetValues();
76 static XtGeometryResult GeometryManager(), PreferredGeometry();
77 static void ChangeManaged();
78 static Boolean Layout();
80 FormClassRec formClassRec = {
81 { /* core_class fields */
82 /* superclass */ (WidgetClass) &constraintClassRec,
83 /* class_name */ "Form",
84 /* widget_size */ sizeof(FormRec),
85 /* class_initialize */ ClassInitialize,
86 /* class_part_init */ ClassPartInitialize,
87 /* class_inited */ FALSE,
88 /* initialize */ Initialize,
89 /* initialize_hook */ NULL,
90 /* realize */ XtInheritRealize,
91 /* actions */ NULL,
92 /* num_actions */ 0,
93 /* resources */ resources,
94 /* num_resources */ XtNumber(resources),
95 /* xrm_class */ NULLQUARK,
96 /* compress_motion */ TRUE,
97 /* compress_exposure */ TRUE,
98 /* compress_enterleave*/ TRUE,
99 /* visible_interest */ FALSE,
100 /* destroy */ NULL,
101 /* resize */ Resize,
102 /* expose */ XtInheritExpose,
103 /* set_values */ SetValues,
104 /* set_values_hook */ NULL,
105 /* set_values_almost */ XtInheritSetValuesAlmost,
106 /* get_values_hook */ NULL,
107 /* accept_focus */ NULL,
108 /* version */ XtVersion,
109 /* callback_private */ NULL,
110 /* tm_table */ NULL,
111 /* query_geometry */ PreferredGeometry,
112 /* display_accelerator*/ XtInheritDisplayAccelerator,
113 /* extension */ NULL
115 { /* composite_class fields */
116 /* geometry_manager */ GeometryManager,
117 /* change_managed */ ChangeManaged,
118 /* insert_child */ XtInheritInsertChild,
119 /* delete_child */ XtInheritDeleteChild,
120 /* extension */ NULL
122 { /* constraint_class fields */
123 /* subresourses */ formConstraintResources,
124 /* subresource_count */ XtNumber(formConstraintResources),
125 /* constraint_size */ sizeof(FormConstraintsRec),
126 /* initialize */ ConstraintInitialize,
127 /* destroy */ NULL,
128 /* set_values */ ConstraintSetValues,
129 /* extension */ NULL
131 { /* form_class fields */
132 /* layout */ Layout
136 WidgetClass formWidgetClass = (WidgetClass)&formClassRec;
138 /****************************************************************
140 * Private Procedures
142 ****************************************************************/
145 static XrmQuark XtQChainLeft, XtQChainRight, XtQChainTop,
146 XtQChainBottom, XtQRubber;
148 #define done(address, type) \
149 { toVal->size = sizeof(type); \
150 toVal->addr = (caddr_t) address; \
151 return; \
154 /* ARGSUSED */
155 static void _CvtStringToEdgeType(args, num_args, fromVal, toVal)
156 XrmValuePtr args; /* unused */
157 Cardinal *num_args; /* unused */
158 XrmValuePtr fromVal;
159 XrmValuePtr toVal;
161 static XtEdgeType edgeType;
162 XrmQuark q;
163 char lowerName[1000];
165 XmuCopyISOLatin1Lowered (lowerName, (char*)fromVal->addr);
166 q = XrmStringToQuark(lowerName);
167 if (q == XtQChainLeft) {
168 edgeType = XtChainLeft;
169 done(&edgeType, XtEdgeType);
171 if (q == XtQChainRight) {
172 edgeType = XtChainRight;
173 done(&edgeType, XtEdgeType);
175 if (q == XtQChainTop) {
176 edgeType = XtChainTop;
177 done(&edgeType, XtEdgeType);
179 if (q == XtQChainBottom) {
180 edgeType = XtChainBottom;
181 done(&edgeType, XtEdgeType);
183 if (q == XtQRubber) {
184 edgeType = XtRubber;
185 done(&edgeType, XtEdgeType);
187 XtStringConversionWarning(fromVal->addr, "edgeType");
188 toVal->addr = NULL;
189 toVal->size = 0;
192 static void ClassInitialize()
194 static XtConvertArgRec parentCvtArgs[] = {
195 {XtBaseOffset, (caddr_t)XtOffset(Widget, core.parent), sizeof(Widget)}
197 XawInitializeWidgetSet();
198 XtQChainLeft = XrmStringToQuark("chainleft");
199 XtQChainRight = XrmStringToQuark("chainright");
200 XtQChainTop = XrmStringToQuark("chaintop");
201 XtQChainBottom = XrmStringToQuark("chainbottom");
202 XtQRubber = XrmStringToQuark("rubber");
204 XtAddConverter( XtRString, XtREdgeType, _CvtStringToEdgeType, NULL, 0 );
205 XtAddConverter( XtRString, XtRWidget, XmuCvtStringToWidget,
206 parentCvtArgs, XtNumber(parentCvtArgs) );
209 static void ClassPartInitialize(class)
210 WidgetClass class;
212 register FormWidgetClass c = (FormWidgetClass)class;
214 if (c->form_class.layout == XtInheritLayout)
215 c->form_class.layout = Layout;
219 /* ARGSUSED */
220 static void Initialize(request, new)
221 Widget request, new;
223 FormWidget fw = (FormWidget)new;
225 fw->form.old_width = fw->core.width;
226 fw->form.old_height = fw->core.height;
227 fw->form.no_refigure = False;
228 fw->form.needs_relayout = False;
229 fw->form.resize_in_layout = True;
233 static void RefigureLocations(w)
234 FormWidget w;
236 if (w->form.no_refigure) {
237 w->form.needs_relayout = True;
239 else {
240 (*((FormWidgetClass)w->core.widget_class)->form_class.layout)
241 ( w, w->core.width, w->core.height );
242 w->form.needs_relayout = False;
246 static void LayoutChild(w)
247 Widget w;
249 FormConstraints form = (FormConstraints)w->core.constraints;
250 Position x, y;
251 Widget ref;
253 switch (form->form.layout_state) {
255 case LayoutPending:
256 form->form.layout_state = LayoutInProgress;
257 break;
259 case LayoutDone:
260 return;
262 case LayoutInProgress:
264 String subs[2];
265 Cardinal num_subs = 2;
266 subs[0] = w->core.name;
267 subs[1] = w->core.parent->core.name;
268 XtAppWarningMsg(XtWidgetToApplicationContext(w),
269 "constraintLoop","xawFormLayout","XawToolkitError",
270 "constraint loop detected while laying out child '%s' in FormWidget '%s'",
271 subs, &num_subs);
272 return;
275 x = form->form.dx;
276 y = form->form.dy;
277 if ((ref = form->form.horiz_base) != (Widget)NULL) {
278 LayoutChild(ref);
279 x += ref->core.x + ref->core.width + (ref->core.border_width << 1);
281 if ((ref = form->form.vert_base) != (Widget)NULL) {
282 LayoutChild(ref);
283 y += ref->core.y + ref->core.height + (ref->core.border_width << 1);
285 XtMoveWidget( w, x, y );
286 form->form.layout_state = LayoutDone;
290 /* ARGSUSED */
291 static Boolean Layout(fw, width, height)
292 FormWidget fw;
293 Dimension width, height;
295 int num_children = fw->composite.num_children;
296 WidgetList children = fw->composite.children;
297 Widget *childP;
298 Position maxx, maxy;
299 Boolean ret_val;
301 for (childP = children; childP - children < num_children; childP++) {
302 FormConstraints form = (FormConstraints)(*childP)->core.constraints;
303 form->form.layout_state = LayoutPending;
306 maxx = maxy = 1;
307 for (childP = children; childP - children < num_children; childP++) {
308 if (XtIsManaged(*childP)) {
309 Position x, y;
310 LayoutChild(*childP);
311 x = (*childP)->core.x + (*childP)->core.width
312 + ((*childP)->core.border_width << 1);
313 y = (*childP)->core.y + (*childP)->core.height
314 + ((*childP)->core.border_width << 1);
315 if (maxx < x) maxx = x;
316 if (maxy < y) maxy = y;
320 fw->form.preferred_width = (maxx += fw->form.default_spacing);
321 fw->form.preferred_height = (maxy += fw->form.default_spacing);
323 if (fw->form.resize_in_layout
324 && (maxx != fw->core.width || maxy != fw->core.height)) {
325 XtGeometryResult result;
326 result = XtMakeResizeRequest((Widget)fw,
327 (Dimension)maxx, (Dimension)maxy,
328 (Dimension*)&maxx, (Dimension*)&maxy );
329 if (result == XtGeometryAlmost)
330 result = XtMakeResizeRequest((Widget)fw,
331 (Dimension)maxx, (Dimension)maxy,
332 NULL, NULL );
333 fw->form.old_width = fw->core.width;
334 fw->form.old_height = fw->core.height;
335 ret_val = (result == XtGeometryYes);
336 } else ret_val = False;
338 return ret_val;
342 static Position TransformCoord(loc, old, new, type)
343 register Position loc;
344 Dimension old, new;
345 XtEdgeType type;
347 if (type == XtRubber) {
348 if ( ((int) old) > 0)
349 loc = (loc * new) / old;
351 else if (type == XtChainBottom || type == XtChainRight)
352 loc += (Position)new - (Position)old;
354 /* I don't see any problem with returning values less than zero. */
356 return (loc);
360 static void Resize(w)
361 Widget w;
363 FormWidget fw = (FormWidget)w;
364 WidgetList children = fw->composite.children;
365 int num_children = fw->composite.num_children;
366 Widget *childP;
367 Position x, y;
368 Dimension width, height;
370 for (childP = children; childP - children < num_children; childP++) {
371 FormConstraints form = (FormConstraints)(*childP)->core.constraints;
372 if (!XtIsManaged(*childP)) continue;
373 x = TransformCoord( (*childP)->core.x, fw->form.old_width,
374 fw->core.width, form->form.left );
375 y = TransformCoord( (*childP)->core.y, fw->form.old_height,
376 fw->core.height, form->form.top );
378 form->form.virtual_width =
379 TransformCoord((Position)((*childP)->core.x
380 + form->form.virtual_width
381 + 2 * (*childP)->core.border_width),
382 fw->form.old_width, fw->core.width,
383 form->form.right )
384 - (x + 2 * (*childP)->core.border_width);
386 form->form.virtual_height =
387 TransformCoord((Position)((*childP)->core.y
388 + form->form.virtual_height
389 + 2 * (*childP)->core.border_width),
390 fw->form.old_height, fw->core.height,
391 form->form.bottom )
392 - ( y + 2 * (*childP)->core.border_width);
394 width = (Dimension)
395 (form->form.virtual_width < 1) ? 1 : form->form.virtual_width;
396 height = (Dimension)
397 (form->form.virtual_height < 1) ? 1 : form->form.virtual_height;
399 XtConfigureWidget( *childP, x, y, (Dimension)width, (Dimension)height,
400 (*childP)->core.border_width );
403 fw->form.old_width = fw->core.width;
404 fw->form.old_height = fw->core.height;
408 /* ARGSUSED */
409 static XtGeometryResult GeometryManager(w, request, reply)
410 Widget w;
411 XtWidgetGeometry *request;
412 XtWidgetGeometry *reply; /* RETURN */
414 FormConstraints form = (FormConstraints)w->core.constraints;
415 XtWidgetGeometry allowed;
417 if ((request->request_mode & ~(XtCWQueryOnly | CWWidth | CWHeight)) ||
418 !form->form.allow_resize)
419 return XtGeometryNo;
421 if (request->request_mode & CWWidth)
422 allowed.width = request->width;
423 else
424 allowed.width = w->core.width;
426 if (request->request_mode & CWHeight)
427 allowed.height = request->height;
428 else
429 allowed.height = w->core.height;
431 if (allowed.width == w->core.width && allowed.height == w->core.height)
432 return XtGeometryNo;
434 if (!(request->request_mode & XtCWQueryOnly)) {
435 /* reset virtual width and height. */
436 form->form.virtual_width = w->core.width = allowed.width;
437 form->form.virtual_height = w->core.height = allowed.height;
438 RefigureLocations( (FormWidget)w->core.parent );
440 return XtGeometryYes;
445 /* ARGSUSED */
446 static Boolean SetValues(current, request, new)
447 Widget current, request, new;
449 return( FALSE );
453 /* ARGSUSED */
454 static void ConstraintInitialize(request, new)
455 Widget request, new;
457 FormConstraints form = (FormConstraints)new->core.constraints;
458 FormWidget fw = (FormWidget)new->core.parent;
460 form->form.virtual_width = (int) new->core.width;
461 form->form.virtual_height = (int) new->core.height;
463 if (form->form.dx == default_value)
464 form->form.dx = fw->form.default_spacing;
466 if (form->form.dy == default_value)
467 form->form.dy = fw->form.default_spacing;
470 /* ARGSUSED */
471 static Boolean ConstraintSetValues(current, request, new)
472 Widget current, request, new;
474 return( FALSE );
477 static void ChangeManaged(w)
478 Widget w;
480 FormWidget fw = (FormWidget)w;
481 FormConstraints form;
482 WidgetList children, childP;
483 int num_children = fw->composite.num_children;
484 Widget child;
487 * Reset virtual width and height for all children.
490 for (children = childP = fw->composite.children ;
491 childP - children < num_children; childP++) {
492 child = *childP;
493 if (XtIsManaged(child)) {
494 form = (FormConstraints)child->core.constraints;
497 * If the size is one (1) then we must not change the virtual sizes, as
498 * they contain useful information. If someone actually wants a widget of
499 * width or height one (1) in a form widget he will lose, can't win them all.
501 * Chris D. Peterson 2/9/89.
505 if ( child->core.width != 1)
506 form->form.virtual_width = (int) child->core.width;
507 if ( child->core.height != 1)
508 form->form.virtual_height = (int) child->core.height;
511 RefigureLocations( (FormWidget)w );
515 static XtGeometryResult PreferredGeometry( widget, request, reply )
516 Widget widget;
517 XtWidgetGeometry *request, *reply;
519 FormWidget w = (FormWidget)widget;
521 reply->width = w->form.preferred_width;
522 reply->height = w->form.preferred_height;
523 reply->request_mode = CWWidth | CWHeight;
524 if ( request->request_mode & (CWWidth | CWHeight) ==
525 reply->request_mode & CWWidth | CWHeight
526 && request->width == reply->width
527 && request->height == reply->height)
528 return XtGeometryYes;
529 else if (reply->width == w->core.width && reply->height == w->core.height)
530 return XtGeometryNo;
531 else
532 return XtGeometryAlmost;
536 /**********************************************************************
538 * Public routines
540 **********************************************************************/
543 * Set or reset figuring (ignored if not realized)
546 void XawFormDoLayout(w, doit)
547 Widget w;
548 Boolean doit;
550 register FormWidget fw = (FormWidget)w;
552 fw->form.no_refigure = !doit;
554 if ( XtIsRealized(w) && fw->form.needs_relayout )
555 RefigureLocations( fw );