~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/3rdparty/qmon/Xbae/Caption.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright(c) 1992 Bell Communications Research, Inc. (Bellcore)
 
3
 * Copyright(c) 1999 Andrew Lister
 
4
 *
 
5
 *                        All rights reserved
 
6
 * Permission to use, copy, modify and distribute this material for
 
7
 * any purpose and without fee is hereby granted, provided that the
 
8
 * above copyright notice and this permission notice appear in all
 
9
 * copies, and that the name of Bellcore not be used in advertising
 
10
 * or publicity pertaining to this material without the specific,
 
11
 * prior written permission of an authorized representative of
 
12
 * Bellcore.
 
13
 *
 
14
 * BELLCORE MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES, EX-
 
15
 * PRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
 
16
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 
17
 * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST IN-
 
18
 * FRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS.  THE
 
19
 * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL BELLCORE OR
 
20
 * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
 
21
 * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELAT-
 
22
 * ING TO THE SOFTWARE.
 
23
 *
 
24
 * CaptionWidget Author: Andrew Wason, Bellcore, aw@bae.bellcore.com
 
25
 * 
 
26
 * $Id$
 
27
 */
 
28
 
 
29
/*
 
30
 * Caption.c - displays a caption label next to it's child.
 
31
 */
 
32
 
 
33
#ifdef HAVE_CONFIG_H
 
34
#include <config.h>
 
35
#endif
 
36
 
 
37
#include <ctype.h>
 
38
#include <X11/StringDefs.h>
 
39
#include <Xm/XmP.h>
 
40
#include <Xm/Label.h>
 
41
#include "Macros.h"
 
42
#include "CaptionP.h"
 
43
 
 
44
#ifndef tolower
 
45
#define tolower(c)      ((c) - 'A' + 'a')
 
46
#endif
 
47
 
 
48
#define OffsetOf(field)        XtOffsetOf(XbaeCaptionRec, field)
 
49
 
 
50
static XtResource resources[] = {
 
51
    { XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList),
 
52
          OffsetOf(caption.font_list), XmRImmediate, (XtPointer) NULL },
 
53
    { XmNlabelAlignment, XmCLabelAlignment, XmRLabelAlignment,
 
54
          sizeof(XbaeLabelAlignment), OffsetOf(caption.label_alignment),
 
55
          XmRImmediate, (XtPointer) XbaeAlignmentCenter },
 
56
    { XmNlabelOffset, XmCLabelOffset, XmRInt, sizeof(int),
 
57
          OffsetOf(caption.label_offset), XmRImmediate, (XtPointer) 0 },
 
58
    { XmNlabelPixmap, XmCLabelPixmap, XmRManForegroundPixmap, sizeof(Pixmap),
 
59
          OffsetOf(caption.label_pixmap),
 
60
          XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP },
 
61
    { XmNlabelPosition, XmCLabelPosition, XmRLabelPosition,
 
62
          sizeof(XbaeLabelPosition), OffsetOf(caption.label_position),
 
63
          XmRImmediate, (XtPointer) XbaePositionLeft },
 
64
    { XmNlabelString, XmCXmString, XmRXmString, sizeof(XmString),
 
65
          OffsetOf(caption.label_string), XmRImmediate, (XtPointer) NULL },
 
66
    { XmNlabelTextAlignment, XmCAlignment, XmRAlignment, sizeof(unsigned char),
 
67
          OffsetOf(caption.label_text_alignment),
 
68
          XmRImmediate, (XtPointer) XmALIGNMENT_CENTER },
 
69
    { XmNlabelType, XmCLabelType, XmRLabelType, sizeof(unsigned char),
 
70
          OffsetOf(caption.label_type), XmRImmediate, (XtPointer) XmSTRING },
 
71
};
 
72
 
 
73
#undef OffsetOf
 
74
 
 
75
/*
 
76
 * Macro to retrieve our label and the user's child.
 
77
 */
 
78
#define LabelChild(w)     (((CompositeWidget)w)->composite.children[0])
 
79
#define UserChild(w)      (((CompositeWidget)w)->composite.children[1])
 
80
 
 
81
#define HaveUserChild(w)  (((CompositeWidget)w)->composite.num_children > 1 \
 
82
                           && XtIsManaged(UserChild(w)))
 
83
 
 
84
 
 
85
/*
 
86
 * Declaration of methods
 
87
 */
 
88
static void ClassInitialize P((void));
 
89
static void Initialize P((Widget, Widget, ArgList, Cardinal *));
 
90
static void InsertChild P((Widget));
 
91
static Boolean SetValues P((Widget, Widget, Widget, ArgList, Cardinal *));
 
92
static void SetValuesAlmost P((Widget, Widget, XtWidgetGeometry *,
 
93
                               XtWidgetGeometry *));
 
94
static void GetValuesHook P((Widget, ArgList, Cardinal *));
 
95
static void Resize P((Widget));
 
96
static void ChangeManaged P((Widget));
 
97
static XtGeometryResult GeometryManager P((Widget, XtWidgetGeometry *,
 
98
                                           XtWidgetGeometry *));
 
99
static XtGeometryResult QueryGeometry P((Widget, XtWidgetGeometry *,
 
100
                                         XtWidgetGeometry *));
 
101
 
 
102
/*
 
103
 * Private functions
 
104
 */
 
105
static void ComputeSize P((XbaeCaptionWidget, Dimension *, Dimension *,
 
106
                            Dimension, Dimension, Dimension));
 
107
static void ComputeUserChildSize P((XbaeCaptionWidget, Dimension, Dimension,
 
108
                                     Dimension *, Dimension *, Dimension));
 
109
 
 
110
static void Layout P((XbaeCaptionWidget, Boolean));
 
111
static Boolean CompareStrings P((String, String));
 
112
 
 
113
/*
 
114
 * Type converters
 
115
 */
 
116
static Boolean CvtStringToLabelPosition P((Display *, XrmValuePtr, Cardinal *,
 
117
                                            XrmValuePtr, XrmValuePtr,
 
118
                                            XtPointer *));
 
119
static Boolean CvtStringToLabelAlignment P((Display *, XrmValuePtr,
 
120
                                             Cardinal *, XrmValuePtr,
 
121
                                             XrmValuePtr, XtPointer *));
 
122
 
 
123
 
 
124
XbaeCaptionClassRec xbaeCaptionClassRec = {
 
125
    {
 
126
    /* core_class fields */
 
127
        /* superclass                        */ (WidgetClass) &xmManagerClassRec,
 
128
        /* class_name                        */ "XbaeCaption",
 
129
        /* widget_size                        */ sizeof(XbaeCaptionRec),
 
130
        /* class_initialize                */ ClassInitialize,
 
131
        /* class_part_initialize        */ NULL,
 
132
        /* class_inited                        */ False,
 
133
        /* initialize                        */ (XtInitProc)Initialize,
 
134
        /* initialize_hook                */ NULL,
 
135
        /* realize                        */ XtInheritRealize,
 
136
        /* actions                        */ NULL,
 
137
        /* num_actions                        */ 0,
 
138
        /* resources                        */ resources,
 
139
        /* num_resources                */ XtNumber(resources),
 
140
        /* xrm_class                        */ NULLQUARK,
 
141
        /* compress_motion                */ True,
 
142
        /* compress_exposure                */ XtExposeCompressMaximal,
 
143
        /* compress_enterleave                */ True,
 
144
        /* visible_interest                */ False,
 
145
        /* destroy                        */ NULL,
 
146
        /* resize                        */ (XtWidgetProc)Resize,
 
147
        /* expose                        */ _XmRedisplayGadgets,
 
148
        /* set_values                        */ (XtSetValuesFunc)SetValues,
 
149
        /* set_values_hook                */ NULL,
 
150
        /* set_values_almost                */ (XtAlmostProc)SetValuesAlmost,
 
151
        /* get_values_hook                */ (XtArgsProc)GetValuesHook,
 
152
        /* accept_focus                        */ NULL,
 
153
        /* version                        */ XtVersion,
 
154
        /* callback_private                */ NULL,
 
155
        /* tm_table                        */ XtInheritTranslations,
 
156
        /* query_geometry                */ (XtGeometryHandler)QueryGeometry,
 
157
        /* display_accelerator                */ NULL,
 
158
        /* extension                        */ NULL
 
159
    },
 
160
    {
 
161
    /* composite_class fields */
 
162
        /* geometry_manager                */ GeometryManager,
 
163
        /* change_managed                */ (XtWidgetProc)ChangeManaged,
 
164
        /* insert_child                        */ InsertChild,
 
165
        /* delete_child                        */ XtInheritDeleteChild,
 
166
        /* extension                        */ NULL,
 
167
    },
 
168
    {
 
169
    /* constraint_class fields */
 
170
        /* resources                        */ NULL,
 
171
        /* num_resources                */ 0,
 
172
        /* constraint_size                */ 0,
 
173
        /* initialize                        */ NULL,
 
174
        /* destroy                        */ NULL,
 
175
        /* set_values                        */ NULL,
 
176
        /* extension                        */ NULL
 
177
    },
 
178
    {
 
179
    /* manager_class fields */
 
180
        /* translations                        */  XtInheritTranslations,
 
181
        /* syn_resources                */  NULL,
 
182
        /* num_syn_resources                */  0,
 
183
        /* syn_constraint_resources        */  NULL,
 
184
        /* num_syn_constraint_resources */  0,
 
185
        /* parent_process                */  XmInheritParentProcess,
 
186
        /* extension                        */  NULL
 
187
    },
 
188
    {
 
189
    /* caption_class fields */
 
190
        /* extension                        */ NULL,
 
191
    }
 
192
};
 
193
 
 
194
WidgetClass xbaeCaptionWidgetClass = (WidgetClass)&xbaeCaptionClassRec;
 
195
 
 
196
 
 
197
static void
 
198
ClassInitialize()
 
199
{
 
200
    XtSetTypeConverter(XmRString, XmRLabelAlignment,
 
201
                       CvtStringToLabelAlignment, NULL, 0,
 
202
                       XtCacheAll, NULL);
 
203
 
 
204
    XtSetTypeConverter(XmRString, XmRLabelPosition,
 
205
                       CvtStringToLabelPosition, NULL, 0,
 
206
                       XtCacheAll, NULL);
 
207
}
 
208
 
 
209
/* ARGSUSED */
 
210
static void
 
211
Initialize(req, n, args, num_args)
 
212
Widget req, n;
 
213
ArgList args;
 
214
Cardinal *num_args;
 
215
{
 
216
    XbaeCaptionWidget new = (XbaeCaptionWidget)n;
 
217
    /*
 
218
     * Validate our labelPosition
 
219
     */
 
220
    switch (new->caption.label_position) {
 
221
    case XbaePositionLeft:
 
222
    case XbaePositionRight:
 
223
    case XbaePositionTop:
 
224
    case XbaePositionBottom:
 
225
        break;
 
226
    default:
 
227
        XtAppWarningMsg(
 
228
            XtWidgetToApplicationContext((Widget)new),
 
229
            "initialize", "badLabelPosition", "XbaeCaption",
 
230
            "XbaeCaption: Invalid label position.",
 
231
            (String *) NULL, (Cardinal *) NULL);
 
232
        new->caption.label_position = XbaePositionLeft;
 
233
        break;
 
234
    }
 
235
 
 
236
    /*
 
237
     * Validate our labelAlignment
 
238
     */
 
239
    switch (new->caption.label_alignment) {
 
240
    case XbaeAlignmentTopOrLeft:
 
241
    case XbaeAlignmentCenter:
 
242
    case XbaeAlignmentBottomOrRight:
 
243
        break;
 
244
    default:
 
245
        XtAppWarningMsg(
 
246
            XtWidgetToApplicationContext((Widget)new),
 
247
            "initialize", "badLabelAlignment", "XbaeCaption",
 
248
            "XbaeCaption: Invalid label alignment.",
 
249
            (String *) NULL, (Cardinal *) NULL);
 
250
        new->caption.label_alignment = XbaeAlignmentCenter;
 
251
    }
 
252
 
 
253
 
 
254
    /*
 
255
     * Create the label with our name, so if no labelString is specified,
 
256
     * it will use our name as it's label.
 
257
     */
 
258
    (void)
 
259
        XtVaCreateManagedWidget(XtName((Widget)new),
 
260
                                xmLabelWidgetClass, (Widget)new,
 
261
                                XmNbackground,        new->core.background_pixel,
 
262
                                XmNforeground,        new->manager.foreground,
 
263
                                XmNfontList,        new->caption.font_list,
 
264
                                XmNlabelType,        new->caption.label_type,
 
265
                                XmNalignment,
 
266
                                        new->caption.label_text_alignment,
 
267
                                XmNlabelString,        new->caption.label_string,
 
268
                                XmNlabelPixmap,        new->caption.label_pixmap,
 
269
                                XmNborderWidth,        0,
 
270
                                NULL);
 
271
 
 
272
    /*
 
273
     * The label makes a copy of these, so NULL them out
 
274
     * (we don't want to point to the user's data).
 
275
     * get_values_hook will handle a get_values on these.
 
276
     */
 
277
    new->caption.label_string = NULL;
 
278
    new->caption.font_list = NULL;
 
279
 
 
280
    /*
 
281
     * We are the same size as our label.  We ignore user specified
 
282
     * width/height.
 
283
     */
 
284
    new->core.width = LabelChild(new)->core.width;
 
285
    new->core.height = LabelChild(new)->core.height;
 
286
}
 
287
 
 
288
static void
 
289
InsertChild(w)
 
290
Widget w;
 
291
{
 
292
    if (((CompositeWidget)XtParent(w))->composite.num_children > 1) {
 
293
        XtAppWarningMsg(
 
294
            XtWidgetToApplicationContext(w),
 
295
            "insertChild", "badChild", "XbaeCaption",
 
296
            "XbaeCaption: Cannot add more than one child.",
 
297
            (String *)NULL, (Cardinal *)NULL);
 
298
        return;
 
299
    }
 
300
 
 
301
    (*((CompositeWidgetClass)
 
302
       (xbaeCaptionWidgetClass->core_class.superclass))->composite_class.
 
303
     insert_child) (w);
 
304
}
 
305
 
 
306
 
 
307
/* ARGSUSED */
 
308
static Boolean
 
309
SetValues(cur, req, nw, args, num_args)
 
310
Widget cur, req, nw;
 
311
ArgList args;
 
312
Cardinal *num_args;
 
313
{
 
314
    XbaeCaptionWidget current = (XbaeCaptionWidget)cur;
 
315
    XbaeCaptionWidget new = (XbaeCaptionWidget)nw;
 
316
    Dimension old_label_width, old_label_height;
 
317
    Boolean layout = False;
 
318
    int n;
 
319
    Arg largs[7];
 
320
 
 
321
#define NE(field)       (current->field != new->field)
 
322
#define EQ(field)       (current->field == new->field)
 
323
 
 
324
    /*
 
325
     * Validate our labelPosition
 
326
     */
 
327
    if (NE(caption.label_position)) {
 
328
        switch (new->caption.label_position) {
 
329
        case XbaePositionLeft:
 
330
        case XbaePositionRight:
 
331
        case XbaePositionTop:
 
332
        case XbaePositionBottom:
 
333
            break;
 
334
        default:
 
335
            XtAppWarningMsg(
 
336
                XtWidgetToApplicationContext((Widget)new),
 
337
                "setValues", "badLabelPosition", "XbaeCaption",
 
338
                "XbaeCaption: Invalid label position.",
 
339
                (String *) NULL, (Cardinal *) NULL);
 
340
            new->caption.label_position = current->caption.label_position;
 
341
        }
 
342
    }
 
343
 
 
344
    /*
 
345
     * Validate our labelAlignment
 
346
     */
 
347
    if (NE(caption.label_alignment)) {
 
348
        switch (new->caption.label_alignment) {
 
349
        case XbaeAlignmentTopOrLeft:
 
350
        case XbaeAlignmentCenter:
 
351
        case XbaeAlignmentBottomOrRight:
 
352
            break;
 
353
        default:
 
354
            XtAppWarningMsg(
 
355
                XtWidgetToApplicationContext((Widget)new),
 
356
                "setValues", "badLabelAlignment", "XbaeCaption",
 
357
                "XbaeCaption: Invalid label alignment.",
 
358
                (String *) NULL, (Cardinal *) NULL);
 
359
            new->caption.label_alignment = current->caption.label_alignment;
 
360
        }
 
361
    }
 
362
 
 
363
    /*
 
364
     * Save labels size in case XtSetValues changes it below.
 
365
     */
 
366
    old_label_width = LabelChild(new)->core.width;
 
367
    old_label_height = LabelChild(new)->core.height;
 
368
 
 
369
    /*
 
370
     * Pass through resources to our label.  Our geometry_manager
 
371
     * will let it change size if it needs to.
 
372
     */
 
373
    n = 0;
 
374
    if (NE(caption.label_type)) {
 
375
        XtSetArg(largs[n], XmNlabelType,new->caption.label_type);        n++;
 
376
    }
 
377
    if (NE(caption.label_text_alignment)) {
 
378
        XtSetArg(largs[n], XmNalignment,
 
379
                 new->caption.label_text_alignment);                        n++;
 
380
    }
 
381
    if (NE(caption.label_string)) {
 
382
        XtSetArg(largs[n], XmNlabelString, new->caption.label_string);        n++;
 
383
    }
 
384
    if (NE(caption.label_pixmap)) {
 
385
        XtSetArg(largs[n], XmNlabelPixmap, new->caption.label_pixmap);        n++;
 
386
    }
 
387
    if (NE(caption.font_list)) {
 
388
        XtSetArg(largs[n], XmNfontList, new->caption.font_list);        n++;
 
389
    }
 
390
    if (NE(core.background_pixel)) {
 
391
        XtSetArg(largs[n], XmNbackground, new->core.background_pixel);        n++;
 
392
    }
 
393
    if (NE(manager.foreground)) {
 
394
        XtSetArg(largs[n], XmNforeground, new->manager.foreground);        n++;
 
395
    }
 
396
    if (n) {
 
397
        XtSetValues(LabelChild(new), largs, n);
 
398
 
 
399
        /*
 
400
         * The label makes a copy of these, so NULL them out
 
401
         * (we don't want to point to the user's data).
 
402
         * get_values_hook will handle a get_values on these.
 
403
         */
 
404
        new->caption.label_string = NULL;
 
405
        new->caption.font_list = NULL;
 
406
    }
 
407
 
 
408
    /*
 
409
     * Calculate a new size if the label changed size, or if offset changed,
 
410
     * or if alignment or position changed in a way which requires a new
 
411
     * size.  Our resize or set_values_almost methods will lay things out.
 
412
     */
 
413
    if (old_label_width != LabelChild(new)->core.width ||
 
414
        old_label_height != LabelChild(new)->core.height ||
 
415
        NE(caption.label_offset) || NE(caption.label_position)) {
 
416
 
 
417
        if (!HaveUserChild(new)) {
 
418
            new->core.width = LabelChild(new)->core.width;
 
419
            new->core.height = LabelChild(new)->core.height;
 
420
        }
 
421
        else
 
422
            ComputeSize(new, &new->core.width, &new->core.height,
 
423
                        UserChild(new)->core.width,
 
424
                        UserChild(new)->core.height,
 
425
                        UserChild(new)->core.border_width);
 
426
 
 
427
        /*
 
428
         * If, after all that, our size didn't change, then we need
 
429
         * to layout (since resize and set_values_almost won't be called).
 
430
         */
 
431
        if (EQ(core.width) && EQ(core.height))
 
432
            layout = True;
 
433
    }
 
434
 
 
435
    /*
 
436
     * If label alignment changed, but our size didn't, then we need to layout
 
437
     * (since resize and set_values_almost won't be called).
 
438
     */
 
439
    if (NE(caption.label_alignment) && EQ(core.width) && EQ(core.height))
 
440
        layout = True;
 
441
 
 
442
    if (layout)
 
443
        Layout(new, True);
 
444
 
 
445
    return False;
 
446
 
 
447
#undef EQ
 
448
#undef NE
 
449
}
 
450
 
 
451
/* ARGSUSED */
 
452
static void
 
453
SetValuesAlmost(o, n, request, reply)
 
454
Widget o;
 
455
Widget n;
 
456
XtWidgetGeometry *request;
 
457
XtWidgetGeometry *reply;
 
458
{
 
459
    XbaeCaptionWidget new = (XbaeCaptionWidget)n;
 
460
    /*
 
461
     * If XtGeometryAlmost, accept compromize - our resize method
 
462
     * will take care of it.
 
463
     */
 
464
    if (reply->request_mode)
 
465
        *request = *reply;
 
466
 
 
467
    /*
 
468
     * If XtGeometryNo, then layout if it was a size change that was denied,
 
469
     * and accept the original geometry.
 
470
     */
 
471
    else {
 
472
        if (request->request_mode & CWWidth ||
 
473
            request->request_mode & CWHeight)
 
474
            Layout(new, True);
 
475
 
 
476
        request->request_mode = 0;
 
477
    }
 
478
}
 
479
 
 
480
static void
 
481
GetValuesHook(w, args, num_args)
 
482
Widget w;
 
483
ArgList args;
 
484
Cardinal *num_args;
 
485
{
 
486
    XbaeCaptionWidget cw = (XbaeCaptionWidget)w;
 
487
    int i;
 
488
 
 
489
    /*
 
490
     * We don't save a copy of the label_string or font_list.
 
491
     * If the user wants these, we get them from the label widget.
 
492
     */
 
493
    for (i = 0; i < *num_args; i++)
 
494
        if (strcmp(args[i].name, XmNlabelString) == 0)
 
495
            XtGetValues(LabelChild(cw), &args[i], 1);
 
496
        else if (strcmp(args[i].name, XmNfontList) == 0)
 
497
            XtGetValues(LabelChild(cw), &args[i], 1);
 
498
}
 
499
 
 
500
/*
 
501
 * Do not configure the user's child if configure is False.
 
502
 * This is for when we are laying out from within our GeometryManager.
 
503
 * Since we are following a XtGeometryYes policy, we shouldn't config
 
504
 * the initiating child (the label never initiates)
 
505
 */
 
506
static void
 
507
#if NeedFunctionPrototypes
 
508
Layout(XbaeCaptionWidget cw, Boolean configure)
 
509
#else
 
510
Layout(cw, configure)
 
511
XbaeCaptionWidget cw;
 
512
Boolean configure;
 
513
#endif
 
514
{
 
515
    Position label_x = 0, label_y = 0;
 
516
    Position user_x = 0, user_y = 0;
 
517
    Dimension user_width, user_height;
 
518
 
 
519
    /*
 
520
     * If we only have the label, position it at 0,0.
 
521
     */
 
522
    if (!HaveUserChild(cw)) {
 
523
        XtMoveWidget(LabelChild(cw), 0, 0);
 
524
        return;
 
525
    }
 
526
 
 
527
    /*
 
528
     * Calculate the positions of our label and user's children.
 
529
     */
 
530
    switch (cw->caption.label_position) {
 
531
 
 
532
    case XbaePositionLeft:
 
533
    case XbaePositionRight:
 
534
        switch (cw->caption.label_alignment) {
 
535
        case XbaeAlignmentTopOrLeft:
 
536
            label_y = 0;
 
537
            break;
 
538
        case XbaeAlignmentCenter:
 
539
            label_y = (int) (cw->core.height / 2) -
 
540
                (int) (LabelChild(cw)->core.height / 2);
 
541
            break;
 
542
        case XbaeAlignmentBottomOrRight:
 
543
            label_y = (int)cw->core.height - (int)LabelChild(cw)->core.height;
 
544
            break;
 
545
        }
 
546
        user_y = 0;
 
547
        break;
 
548
 
 
549
    case XbaePositionTop:
 
550
    case XbaePositionBottom:
 
551
        switch (cw->caption.label_alignment) {
 
552
        case XbaeAlignmentTopOrLeft:
 
553
            label_x = 0;
 
554
            break;
 
555
        case XbaeAlignmentCenter:
 
556
            label_x = (int) (cw->core.width / 2) -
 
557
                (int) (LabelChild(cw)->core.width / 2);
 
558
            break;
 
559
        case XbaeAlignmentBottomOrRight:
 
560
            label_x = (int)cw->core.width - (int)LabelChild(cw)->core.width;
 
561
            break;
 
562
        }
 
563
        user_x = 0;
 
564
        break;
 
565
    }
 
566
 
 
567
 
 
568
    /*
 
569
     * Calculate the positions of our label and user's children.
 
570
     */
 
571
    switch (cw->caption.label_position) {
 
572
 
 
573
    case XbaePositionLeft:
 
574
        if ((int)LabelChild(cw)->core.width + cw->caption.label_offset > 0) {
 
575
            label_x = 0;
 
576
            user_x = (int)LabelChild(cw)->core.width +
 
577
                cw->caption.label_offset;
 
578
        }
 
579
        else {
 
580
            label_x = -cw->caption.label_offset;
 
581
            user_x = 0;
 
582
        }
 
583
        break;
 
584
 
 
585
    case XbaePositionRight:
 
586
        if ((int)LabelChild(cw)->core.width + cw->caption.label_offset > 0)
 
587
            label_x = (int)cw->core.width - (int)LabelChild(cw)->core.width;
 
588
        else
 
589
            label_x = (int)cw->core.width - ((int)LabelChild(cw)->core.width -
 
590
                                             cw->caption.label_offset);
 
591
        user_x = 0;
 
592
        break;
 
593
 
 
594
    case XbaePositionTop:
 
595
        if ((int)LabelChild(cw)->core.height + cw->caption.label_offset > 0) {
 
596
            label_y = 0;
 
597
            user_y = (int)LabelChild(cw)->core.height +
 
598
                cw->caption.label_offset;
 
599
        }
 
600
        else {
 
601
            label_y = -cw->caption.label_offset;
 
602
            user_y = 0;
 
603
        }
 
604
        break;
 
605
 
 
606
    case XbaePositionBottom:
 
607
        user_y = 0;
 
608
        label_y = cw->core.height - LabelChild(cw)->core.height;
 
609
 
 
610
        if ((int)LabelChild(cw)->core.height + cw->caption.label_offset > 0)
 
611
            label_y = (int)cw->core.height - (int)LabelChild(cw)->core.height;
 
612
        else
 
613
            label_y = (int)cw->core.height -
 
614
                ((int)LabelChild(cw)->core.height - cw->caption.label_offset);
 
615
        user_y = 0;
 
616
        break;
 
617
    }
 
618
 
 
619
    /*
 
620
     * Position our label widget.
 
621
     */
 
622
    XtMoveWidget(LabelChild(cw), label_x, label_y);
 
623
 
 
624
 
 
625
    if (configure) {
 
626
        /*
 
627
         * Calculate the size of the user's child widget.
 
628
         */
 
629
        ComputeUserChildSize(cw, cw->core.width, cw->core.height,
 
630
                             &user_width, &user_height,
 
631
                             UserChild(cw)->core.border_width);
 
632
 
 
633
        _XmConfigureObject((Widget)UserChild(cw),
 
634
                           (int)user_x, (int)user_y,
 
635
                           (int)user_width, (int)user_height,
 
636
                           (int)UserChild(cw)->core.border_width);
 
637
    }
 
638
}
 
639
 
 
640
static void
 
641
Resize(w)
 
642
Widget w;
 
643
{
 
644
    Layout((XbaeCaptionWidget)w, True);
 
645
}
 
646
 
 
647
/*
 
648
 * Given a width/height for the caption widget and the border width
 
649
 * of the user's child, compute the width and height of the user's child.
 
650
 */
 
651
static void
 
652
#if NeedFunctionPrototypes
 
653
ComputeUserChildSize(XbaeCaptionWidget cw, Dimension cwWidth,
 
654
                     Dimension cwHeight, Dimension *childWidth,
 
655
                     Dimension *childHeight, Dimension childBorderWidth)
 
656
#else
 
657
ComputeUserChildSize(cw, cwWidth, cwHeight, childWidth, childHeight,
 
658
                     childBorderWidth)
 
659
XbaeCaptionWidget cw;
 
660
Dimension cwWidth;
 
661
Dimension cwHeight;
 
662
Dimension *childWidth;
 
663
Dimension *childHeight;
 
664
Dimension childBorderWidth;
 
665
#endif
 
666
{
 
667
    int width = cwWidth - 2 * childBorderWidth;
 
668
    int height = cwHeight - 2 * childBorderWidth;
 
669
 
 
670
    /*
 
671
     * Remember, cw->caption.label_offset can be negative.
 
672
     * If the label width plus the offset is positive, then the label
 
673
     * is off the edge of the user's child, so we subtract that space
 
674
     * from the user's child space.  Otherwise the label is offset into
 
675
     * the space of the user's child widget, so the user's child gets
 
676
     * the full space and the label will be on top of it (or off the opposite
 
677
     * side).
 
678
     */
 
679
 
 
680
    switch (cw->caption.label_position) {
 
681
    case XbaePositionLeft:
 
682
    case XbaePositionRight:
 
683
        if ((int)LabelChild(cw)->core.width + cw->caption.label_offset > 0)
 
684
            width -= (int)LabelChild(cw)->core.width +
 
685
                cw->caption.label_offset;
 
686
        break;
 
687
    case XbaePositionTop:
 
688
    case XbaePositionBottom:
 
689
        if ((int)LabelChild(cw)->core.height + cw->caption.label_offset > 0)
 
690
            height -= (int)LabelChild(cw)->core.height +
 
691
                cw->caption.label_offset;
 
692
        break;
 
693
    }
 
694
 
 
695
    if (width <= 0)
 
696
        *childWidth = 1;
 
697
    else
 
698
        *childWidth = width;
 
699
 
 
700
    if (height <= 0)
 
701
        *childHeight = 1;
 
702
    else
 
703
        *childHeight = height;
 
704
}
 
705
 
 
706
/*
 
707
 * Compute our size, taking into account the sizes of
 
708
 * both of our children (the user's child size is passed in; we use the
 
709
 * current size of the label child)
 
710
 */
 
711
static void
 
712
#if NeedFunctionPrototypes
 
713
ComputeSize(XbaeCaptionWidget cw, Dimension *cwWidth, Dimension *cwHeight,
 
714
            Dimension childWidth, Dimension childHeight,
 
715
            Dimension childBorderWidth)
 
716
#else
 
717
ComputeSize(cw, cwWidth, cwHeight, childWidth, childHeight, childBorderWidth)
 
718
XbaeCaptionWidget cw;
 
719
Dimension *cwWidth;
 
720
Dimension *cwHeight;
 
721
Dimension childWidth;
 
722
Dimension childHeight;
 
723
Dimension childBorderWidth;
 
724
#endif
 
725
{
 
726
    childWidth += 2 * childBorderWidth;
 
727
    childHeight += 2 * childBorderWidth;
 
728
 
 
729
    /*
 
730
     * Remember, cw->caption.label_offset can be negative.
 
731
     */
 
732
 
 
733
    switch (cw->caption.label_position) {
 
734
    case XbaePositionRight:
 
735
    case XbaePositionLeft:
 
736
        if ((int)LabelChild(cw)->core.width + cw->caption.label_offset > 0)
 
737
            *cwWidth = childWidth + LabelChild(cw)->core.width +
 
738
                cw->caption.label_offset;
 
739
        else
 
740
            *cwWidth = childWidth;
 
741
 
 
742
        *cwHeight = childHeight > LabelChild(cw)->core.height
 
743
                            ? childHeight
 
744
                        : LabelChild(cw)->core.height;
 
745
        break;
 
746
 
 
747
    case XbaePositionTop:
 
748
    case XbaePositionBottom:
 
749
        if ((int)LabelChild(cw)->core.height + cw->caption.label_offset > 0)
 
750
            *cwHeight = childHeight + LabelChild(cw)->core.height +
 
751
                cw->caption.label_offset;
 
752
        else
 
753
            *cwHeight = childHeight;
 
754
 
 
755
        *cwWidth = childWidth > LabelChild(cw)->core.width
 
756
                            ? childWidth
 
757
                        : LabelChild(cw)->core.width;
 
758
        break;
 
759
    }
 
760
}
 
761
 
 
762
static void
 
763
ChangeManaged(w)
 
764
Widget w;
 
765
{
 
766
    XbaeCaptionWidget cw = (XbaeCaptionWidget)w;
 
767
    Dimension width, height;
 
768
    XtGeometryResult result;
 
769
 
 
770
    /*
 
771
     * Figure out what size we want to be.  If we don't have a user child,
 
772
     * we just want to be as big as the label.  Otherwise we must
 
773
     * take the label and user child into account.
 
774
     */
 
775
    if (!HaveUserChild(cw)) {
 
776
        width = LabelChild(cw)->core.width;
 
777
        height = LabelChild(cw)->core.height;
 
778
    }
 
779
    else {
 
780
        ComputeSize(cw, &width, &height,
 
781
                    UserChild(cw)->core.width, UserChild(cw)->core.height,
 
782
                    UserChild(cw)->core.border_width);
 
783
    }
 
784
 
 
785
    /*
 
786
     * If our calculated size is not our current size,
 
787
     * then request our calculated size.
 
788
     */
 
789
    if (width != cw->core.width || height != cw->core.height) {
 
790
        do {
 
791
            result = XtMakeResizeRequest((Widget)cw, width, height,
 
792
                                         &width, &height);
 
793
        } while (result == XtGeometryAlmost);
 
794
    }
 
795
 
 
796
    /*
 
797
     * Layout for the new configuration
 
798
     */
 
799
    Layout(cw, True);
 
800
}
 
801
 
 
802
/* ARGSUSED */
 
803
static XtGeometryResult
 
804
GeometryManager(w, desired, allowed)
 
805
Widget w;
 
806
XtWidgetGeometry *desired, *allowed;
 
807
{
 
808
    XbaeCaptionWidget cw = (XbaeCaptionWidget) XtParent(w);
 
809
    Dimension save_width, save_height, save_border_width;
 
810
 
 
811
#define Wants(flag) (desired->request_mode & flag)
 
812
 
 
813
    /*
 
814
     * If this is our label widget child, and it is querying, then return
 
815
     * Yes since we always grant the labels requests.
 
816
     */
 
817
    if (w == LabelChild(cw) && Wants(XtCWQueryOnly))
 
818
        return XtGeometryYes;
 
819
 
 
820
    /*
 
821
     * Disallow position-only changes for the user's child.
 
822
     */
 
823
    if (w == UserChild(cw) &&
 
824
        !Wants(CWWidth) && !Wants(CWHeight) && !Wants(CWBorderWidth))
 
825
        return XtGeometryNo;
 
826
 
 
827
    /*
 
828
     * Save the childs current geometry in case we have to back it out.
 
829
     */
 
830
    save_width = w->core.width;
 
831
    save_height = w->core.height;
 
832
    save_border_width = w->core.border_width;
 
833
 
 
834
    /*
 
835
     * Store the childs desired geometry into it's widget record.
 
836
     */
 
837
    if (Wants(CWWidth))
 
838
        w->core.width = desired->width;
 
839
    if (Wants(CWHeight))
 
840
        w->core.height = desired->height;
 
841
    if (Wants(CWBorderWidth))
 
842
        w->core.border_width = desired->border_width;
 
843
 
 
844
    /*
 
845
     * If this is our label widget child, then return Yes.  We stored the
 
846
     * changes into the widget above (except for position which we do now),
 
847
     * so Xt will reconfigure the label.
 
848
     * We let our label widget do whatever it wants since we control
 
849
     * when it requests a new size in our set_values.
 
850
     */
 
851
    if (w == LabelChild(cw)) {
 
852
        if (Wants(CWX))
 
853
            w->core.x = desired->x;
 
854
        if (Wants(CWY))
 
855
            w->core.y = desired->y;
 
856
        return XtGeometryYes;
 
857
    }
 
858
 
 
859
    /*
 
860
     * Otherwise this must be our user's child widget.
 
861
     * We will attempt to resize to accomodate it.
 
862
     */
 
863
    else {
 
864
        XtWidgetGeometry request;
 
865
        XtGeometryResult result;
 
866
 
 
867
        /*
 
868
         * Compute the size we want to be based on the new geometry
 
869
         * stored in the user's child above.
 
870
         */
 
871
        ComputeSize(cw, &request.width, &request.height,
 
872
                    w->core.width, w->core.height, w->core.border_width);
 
873
 
 
874
        /*
 
875
         * If our calculated size is not our current size,
 
876
         * then request our calculated size.
 
877
         */
 
878
        if (request.width != cw->core.width ||
 
879
            request.height != cw->core.height) {
 
880
            request.request_mode = 0;
 
881
            if (request.width != cw->core.width)
 
882
                request.request_mode |= CWWidth;
 
883
            if (request.height != cw->core.height)
 
884
                request.request_mode |= CWHeight;
 
885
            if (Wants(XtCWQueryOnly))
 
886
                request.request_mode |= XtCWQueryOnly;
 
887
            do {
 
888
                result = XtMakeGeometryRequest((Widget)cw, &request, &request);
 
889
            } while (result == XtGeometryAlmost);
 
890
 
 
891
            /*
 
892
             * If our request was granted, we need to layout (we are assuming
 
893
             * our parent implements an XtGeometryYes policy and not
 
894
             * XtGeometryDone)
 
895
             */
 
896
            if (result == XtGeometryYes && !Wants(XtCWQueryOnly))
 
897
                Layout(cw, False);
 
898
        }
 
899
        else
 
900
            result = XtGeometryYes;
 
901
 
 
902
        /*
 
903
         * A Yes result means we either got the size we wanted, or we agreed
 
904
         * to a compromise.
 
905
         */
 
906
        if (result == XtGeometryYes) {
 
907
            Dimension childWidth, childHeight;
 
908
 
 
909
            /*
 
910
             * Compute the size of the user's child given the size
 
911
             * we got from our geometry negotiations above.
 
912
             */
 
913
            ComputeUserChildSize(cw, request.width, request.height,
 
914
                                 &childWidth, &childHeight,
 
915
                                 w->core.border_width);
 
916
 
 
917
            /*
 
918
             * If the child wants to change it's position, or it wants
 
919
             * to change it's size but our compromize size is not an
 
920
             * exact fit, then we need to return Almost and the new geometry.
 
921
             */
 
922
            if (((Wants(CWX) || Wants(CWY)) ||
 
923
                 (Wants(CWWidth) && childWidth != w->core.width) ||
 
924
                 (Wants(CWHeight) && childHeight != w->core.height))) {
 
925
                result = XtGeometryAlmost;
 
926
                allowed->request_mode = desired->request_mode & ~(CWX | CWY);
 
927
                allowed->width = childWidth;
 
928
                allowed->height = childHeight;
 
929
                allowed->border_width = w->core.border_width;
 
930
            }
 
931
        }
 
932
 
 
933
        /*
 
934
         * Restore the childs geometry for No or Almost or QueryOnly.
 
935
         */
 
936
        if (result == XtGeometryNo || result == XtGeometryAlmost ||
 
937
            Wants(XtCWQueryOnly)) {
 
938
            w->core.width = save_width;
 
939
            w->core.height = save_height;
 
940
            w->core.border_width = save_border_width;
 
941
        }
 
942
 
 
943
        return result;
 
944
    }
 
945
 
 
946
#undef Wants
 
947
}
 
948
 
 
949
static XtGeometryResult
 
950
QueryGeometry(w, proposed, desired)
 
951
Widget w;
 
952
XtWidgetGeometry *proposed, *desired;
 
953
{
 
954
    XbaeCaptionWidget cw = (XbaeCaptionWidget)w;
 
955
#define Set(bit) (proposed->request_mode & bit)
 
956
 
 
957
    /*
 
958
     * If we don't have a user child, we want to be the size of the label.
 
959
     */
 
960
    if (!HaveUserChild(cw)) {
 
961
        desired->width = LabelChild(cw)->core.width;
 
962
        desired->height = LabelChild(cw)->core.height;
 
963
        desired->request_mode = CWWidth | CWHeight;
 
964
 
 
965
        if (Set(CWWidth) && proposed->width == desired->width &&
 
966
            Set(CWHeight) && proposed->height == desired->height)
 
967
            return XtGeometryYes;
 
968
 
 
969
        if (desired->width == cw->core.width &&
 
970
            desired->height == cw->core.height)
 
971
            return XtGeometryNo;
 
972
 
 
973
        return XtGeometryAlmost;
 
974
    }
 
975
 
 
976
    /*
 
977
     * Otherwise we must take into account what size the user child wants to be
 
978
     */
 
979
    else {
 
980
        XtWidgetGeometry childProposed, childDesired;
 
981
        Dimension childWidth, childHeight, childBorderWidth = 0;
 
982
        Dimension cwWidth, cwHeight;
 
983
        XtGeometryResult result;
 
984
 
 
985
        /*
 
986
         * Get our size based on the proposed size for use in computing
 
987
         * the user's child size.
 
988
         */
 
989
        if (Set(CWWidth))
 
990
            cwWidth = proposed->width;
 
991
        else
 
992
            cwWidth = cw->core.width;
 
993
        if (Set(CWHeight))
 
994
            cwHeight = proposed->height;
 
995
        else
 
996
            cwHeight = cw->core.height;
 
997
 
 
998
        /*
 
999
         * Compute the size of the user's child based on our proposed new size.
 
1000
         */
 
1001
        ComputeUserChildSize(cw, cwWidth, cwHeight,
 
1002
                             &childWidth, &childHeight,
 
1003
                             UserChild(cw)->core.border_width);
 
1004
 
 
1005
        /*
 
1006
         * Build a geometry request to query the user's child with.
 
1007
         */
 
1008
        childProposed.request_mode = 0;
 
1009
        if (Set(CWWidth)) {
 
1010
            childProposed.width = childWidth;
 
1011
            childProposed.request_mode |= CWWidth;
 
1012
        }
 
1013
        if (Set(CWHeight)) {
 
1014
            childProposed.height = childHeight;
 
1015
            childProposed.request_mode |= CWHeight;
 
1016
        }
 
1017
 
 
1018
        /*
 
1019
         * Query the child.
 
1020
         */
 
1021
        result = XtQueryGeometry(UserChild(cw), &childProposed, &childDesired);
 
1022
 
 
1023
        /*
 
1024
         * Save the childs desired geometry.
 
1025
         */
 
1026
        switch (result)
 
1027
        {
 
1028
        case XtGeometryYes:
 
1029
            /* use our computed childWidth and childHeight */
 
1030
            childBorderWidth = UserChild(cw)->core.border_width;
 
1031
            break;
 
1032
        case XtGeometryAlmost:
 
1033
            childWidth = childDesired.width;
 
1034
            childHeight = childDesired.height;
 
1035
            childBorderWidth = childDesired.border_width;
 
1036
            break;
 
1037
        case XtGeometryNo:
 
1038
            childWidth = UserChild(cw)->core.width;
 
1039
            childHeight = UserChild(cw)->core.height;
 
1040
            childBorderWidth = UserChild(cw)->core.border_width;
 
1041
            break;
 
1042
        default:
 
1043
            break;
 
1044
        }
 
1045
 
 
1046
        /*
 
1047
         * Calculate what size we need to be to handle the childs
 
1048
         * desired geometry and store it in our own desired record.
 
1049
         */
 
1050
        ComputeSize(cw, &desired->width, &desired->height,
 
1051
                    childWidth, childHeight, childBorderWidth);
 
1052
 
 
1053
        /*
 
1054
         * If the proposed geometry changed, or if the child cares about
 
1055
         * it's geometry, then set the flag in desired
 
1056
         */
 
1057
        desired->request_mode = 0;
 
1058
        if ((Set(CWWidth) && proposed->width != desired->width) ||
 
1059
            childDesired.request_mode & CWWidth)
 
1060
            desired->request_mode |= CWWidth;
 
1061
        if ((Set(CWHeight) && proposed->height != desired->height) ||
 
1062
            childDesired.request_mode & CWHeight)
 
1063
            desired->request_mode |= CWHeight;
 
1064
 
 
1065
        /*
 
1066
         * If our desired geometry differs from the proposed one, or if
 
1067
         * we care about a geometry which was not proposed, we return
 
1068
         * Almost.  Otherwise we return whatever our child returned.
 
1069
         */
 
1070
        if ((Set(CWWidth) && proposed->width != desired->width) ||
 
1071
            (!Set(CWWidth) && desired->request_mode & CWWidth) ||
 
1072
            (Set(CWHeight) && proposed->height != desired->height) ||
 
1073
            (!Set(CWHeight) && desired->request_mode & CWHeight))
 
1074
            return XtGeometryAlmost;
 
1075
        else
 
1076
            return result;
 
1077
    }
 
1078
 
 
1079
#undef Set
 
1080
}
 
1081
 
 
1082
 
 
1083
/*
 
1084
 * Compare two strings.  The test string must be lower case
 
1085
 * and NULL terminated.  Leading and trailing whitespace in the in
 
1086
 * string is ignored.
 
1087
 */
 
1088
static Boolean
 
1089
CompareStrings(in, test)
 
1090
String in, test;
 
1091
{
 
1092
    /*
 
1093
     * Strip leading whitespace off the in string.
 
1094
     */
 
1095
    while (isspace(*in))
 
1096
        in++;
 
1097
 
 
1098
    for (; *test != '\0' && !isspace(*in); test++, in++) {
 
1099
        char c = *in;
 
1100
 
 
1101
        if (isupper(c))
 
1102
            c = tolower(c);
 
1103
 
 
1104
        if (c != *test)
 
1105
            return False;
 
1106
    }
 
1107
 
 
1108
    if (*test == '\0' && (*in == '\0' || isspace(*in)))
 
1109
        return True;
 
1110
    else
 
1111
        return False;
 
1112
}
 
1113
 
 
1114
/* ARGSUSED */
 
1115
static Boolean
 
1116
CvtStringToLabelPosition(dpy, args, num_args, from, to, data)
 
1117
Display *dpy;
 
1118
XrmValuePtr args;
 
1119
Cardinal *num_args;
 
1120
XrmValuePtr from, to;
 
1121
XtPointer *data;
 
1122
{
 
1123
    static XbaeLabelPosition position;
 
1124
 
 
1125
    if (*num_args != 0)
 
1126
        XtAppWarningMsg(
 
1127
            XtDisplayToApplicationContext(dpy),
 
1128
            "cvtStringToLabelPosition", "wrongParameters",
 
1129
            "XbaeCaption",
 
1130
            "String to LabelPosition conversion needs no extra arguments",
 
1131
            NULL, NULL);
 
1132
 
 
1133
    /*
 
1134
     * User didn't provide enough space
 
1135
     */
 
1136
    if (to->addr != NULL && to->size < sizeof(XbaeLabelPosition)) {
 
1137
        to->size = sizeof(XbaeLabelPosition);
 
1138
        return False;
 
1139
    }
 
1140
 
 
1141
    if (CompareStrings(from->addr, "left"))
 
1142
        position = XbaePositionLeft;
 
1143
    else if (CompareStrings(from->addr, "right"))
 
1144
        position = XbaePositionRight;
 
1145
    else if (CompareStrings(from->addr, "top"))
 
1146
        position = XbaePositionTop;
 
1147
    else if (CompareStrings(from->addr, "bottom"))
 
1148
        position = XbaePositionBottom;
 
1149
    else {
 
1150
        XtDisplayStringConversionWarning(dpy, from->addr, XmRLabelPosition);
 
1151
        return False;
 
1152
    }
 
1153
 
 
1154
    /*
 
1155
     * Store our return value
 
1156
     */
 
1157
    if (to->addr == NULL)
 
1158
        to->addr = (XtPointer) &position;
 
1159
    else
 
1160
        *(XbaeLabelPosition *) to->addr = position;
 
1161
    to->size = sizeof(XbaeLabelPosition);
 
1162
 
 
1163
    return True;
 
1164
}
 
1165
 
 
1166
/* ARGSUSED */
 
1167
static Boolean
 
1168
CvtStringToLabelAlignment(dpy, args, num_args, from, to, data)
 
1169
Display *dpy;
 
1170
XrmValuePtr args;
 
1171
Cardinal *num_args;
 
1172
XrmValuePtr from, to;
 
1173
XtPointer *data;
 
1174
{
 
1175
    static XbaeLabelAlignment alignment;
 
1176
 
 
1177
    if (*num_args != 0)
 
1178
        XtAppWarningMsg(
 
1179
            XtDisplayToApplicationContext(dpy),
 
1180
            "cvtStringToLabelAlignment", "wrongParameters",
 
1181
            "XbaeCaption",
 
1182
            "String to LabelAlignment conversion needs no extra arguments",
 
1183
            NULL, NULL);
 
1184
 
 
1185
    /*
 
1186
     * User didn't provide enough space
 
1187
     */
 
1188
    if (to->addr != NULL && to->size < sizeof(XbaeLabelAlignment)) {
 
1189
        to->size = sizeof(XbaeLabelAlignment);
 
1190
        return False;
 
1191
    }
 
1192
 
 
1193
    if (CompareStrings(from->addr, "toporleft") ||
 
1194
        CompareStrings(from->addr, "top") ||
 
1195
        CompareStrings(from->addr, "left"))
 
1196
        alignment = XbaeAlignmentTopOrLeft;
 
1197
    else if (CompareStrings(from->addr, "center"))
 
1198
        alignment = XbaeAlignmentCenter;
 
1199
    else if (CompareStrings(from->addr, "bottomorright") ||
 
1200
             CompareStrings(from->addr, "bottom") ||
 
1201
             CompareStrings(from->addr, "right"))
 
1202
        alignment = XbaeAlignmentBottomOrRight;
 
1203
    else {
 
1204
        XtDisplayStringConversionWarning(dpy, from->addr, XmRLabelAlignment);
 
1205
        return False;
 
1206
    }
 
1207
 
 
1208
    /*
 
1209
     * Store our return value
 
1210
     */
 
1211
    if (to->addr == NULL)
 
1212
        to->addr = (XtPointer) &alignment;
 
1213
    else
 
1214
        *(XbaeLabelAlignment *) to->addr = alignment;
 
1215
    to->size = sizeof(XbaeLabelAlignment);
 
1216
 
 
1217
    return True;
 
1218
}
 
1219
 
 
1220
Widget
 
1221
XbaeCreateCaption(parent, name, args, ac) 
 
1222
Widget parent;
 
1223
String name;
 
1224
ArgList args;
 
1225
Cardinal ac;
 
1226
 
1227
    return XtCreateWidget(name, xbaeCaptionWidgetClass, parent, args, ac); 
 
1228