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

« back to all changes in this revision

Viewing changes to source/3rdparty/qmon/Xmt310/Xmt/LayoutParse.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
 * Motif Tools Library, Version 3.1
 
3
 * $Id$
 
4
 * 
 
5
 * Written by David Flanagan.
 
6
 * Copyright (c) 1992-2001 by David Flanagan.
 
7
 * All Rights Reserved.  See the file COPYRIGHT for details.
 
8
 * This is open source software.  See the file LICENSE for details.
 
9
 * There is no warranty for this software.  See NO_WARRANTY for details.
 
10
 *
 
11
 * $Log$
 
12
 * Revision 1.1.1.1  2001/07/18 11:06:02  root
 
13
 * Initial checkin.
 
14
 *
 
15
 * Revision 1.2  2001/06/12 16:25:28  andre
 
16
 * *** empty log message ***
 
17
 *
 
18
 *
 
19
 */
 
20
 
 
21
#include <Xmt/Xmt.h>
 
22
#include <Xmt/ConvertersP.h>
 
23
#include <Xmt/Lexer.h>
 
24
#include <Xmt/LayoutP.h>
 
25
 
 
26
/*
 
27
 * we use this structure to accumulate information about rows, columns,
 
28
 * and other things that we'll be creating while parsing the layout
 
29
 * string.  This info never has to leave the parser.
 
30
 */
 
31
typedef struct {
 
32
    Boolean unmanaged;
 
33
    Boolean equal;
 
34
    Boolean color_set;
 
35
    Pixel color;
 
36
    XmtLayoutSpaceType space_type;
 
37
    int space;
 
38
    int space_stretch;
 
39
    int item_stretch;
 
40
} XmtLayoutLocalInfo;
 
41
 
 
42
/* tokens for the parser */
 
43
enum {
 
44
    BITMAP,
 
45
    BOTTOM,
 
46
    BOXED,
 
47
    CTABBED,
 
48
    CAPTION,
 
49
    CENTERED,
 
50
    COL,
 
51
    COLOR,
 
52
    DOUBLEBOXED,
 
53
    DOUBLELINE,
 
54
    EQUAL,
 
55
    ETCHED,
 
56
    EVEN,
 
57
    EVENSPACED,
 
58
    FILLED,
 
59
    FIXED,
 
60
    FLUSHBOTTOM,
 
61
    FLUSHLEFT,
 
62
    FLUSHRIGHT,
 
63
    FLUSHTOP,
 
64
    HSEP,
 
65
    HEIGHT,
 
66
    HIGH,
 
67
    IN,
 
68
    INF,
 
69
    INSIDE,
 
70
    INTERVALSPACED,
 
71
    LCRSPACED,
 
72
    LREVENSPACED,
 
73
    LTABBED,
 
74
    LEFT,
 
75
    LINE,
 
76
    MARGIN,
 
77
    OUT,
 
78
    OUTSIDE,
 
79
    PIXMAP,
 
80
    RTABBED,
 
81
    RIGHT,
 
82
    ROW,
 
83
    SHADOWED,
 
84
    SPACE,
 
85
    STRETCHABLE,
 
86
    STRING,
 
87
    THROUGH,
 
88
    TOP,
 
89
    UNMANAGED,
 
90
    UNRESIZABLE,
 
91
    VSEP,
 
92
    WIDE,
 
93
    WIDTH,
 
94
    EMS,
 
95
    ENS,
 
96
    INCHES,
 
97
    MILLIMETERS,
 
98
    POINTS
 
99
};    
 
100
 
 
101
static String keywords[] = {    
 
102
    "Bitmap",
 
103
    "Bottom",
 
104
    "Boxed",
 
105
    "CTabbed",
 
106
    "Caption",
 
107
    "Centered",
 
108
    "Col",
 
109
    "Color",
 
110
    "DoubleBoxed",
 
111
    "DoubleLine",
 
112
    "Equal",
 
113
    "Etched",
 
114
    "Even",
 
115
    "EvenSpaced",
 
116
    "Filled",
 
117
    "Fixed",
 
118
    "FlushBottom",
 
119
    "FlushLeft",
 
120
    "FlushRight",
 
121
    "FlushTop",
 
122
    "HSep",
 
123
    "Height",
 
124
    "High",
 
125
    "In",
 
126
    "Inf",
 
127
    "Inside",
 
128
    "IntervalSpaced",
 
129
    "LCRSpaced",
 
130
    "LREvenSpaced",
 
131
    "LTabbed",
 
132
    "Left",
 
133
    "Line",
 
134
    "Margin",
 
135
    "Out",
 
136
    "Outside",
 
137
    "Pixmap",
 
138
    "RTabbed",
 
139
    "Right",
 
140
    "Row",
 
141
    "Shadowed",
 
142
    "Space",
 
143
    "Stretchable",
 
144
    "String",
 
145
    "Through",
 
146
    "Top",
 
147
    "Unmanaged",
 
148
    "Unresizable",
 
149
    "VSep",
 
150
    "Wide",
 
151
    "Width",
 
152
    "em",
 
153
    "en",
 
154
    "in",
 
155
    "mm",
 
156
    "pt",
 
157
};
 
158
 
 
159
#define GetToken() XmtLexerGetToken(lw->layout.lexer)
 
160
#define NextToken() XmtLexerNextToken(lw->layout.lexer)
 
161
#define ConsumeToken() XmtLexerConsumeToken(lw->layout.lexer)
 
162
#define GetIntValue() XmtLexerIntValue(lw->layout.lexer)
 
163
#define GetKeyword() XmtLexerKeyValue(lw->layout.lexer)
 
164
#define GetStrValue() XmtLexerStrValue(lw->layout.lexer)
 
165
#define GetStrLength() XmtLexerStrLength(lw->layout.lexer)
 
166
 
 
167
#if NeedFunctionPrototypes
 
168
static int ParsePixelSize(XmtLayoutWidget lw)
 
169
#else
 
170
static int ParsePixelSize(lw)
 
171
XmtLayoutWidget lw;
 
172
#endif
 
173
{
 
174
    XmtLexerToken tok = GetToken();
 
175
    double total, fraction;
 
176
 
 
177
    /* parse optional integer part */
 
178
    if (tok == XmtLexerInteger) {
 
179
        total = (double) GetIntValue();
 
180
        ConsumeToken();
 
181
    }
 
182
    else
 
183
        total = 0.0;
 
184
 
 
185
    /* parse optional fractional part */
 
186
    if (GetToken() == XmtLexerPeriod) {
 
187
        ConsumeToken();
 
188
        if (GetToken() == XmtLexerInteger) {
 
189
            fraction = (double) GetIntValue();
 
190
            ConsumeToken();
 
191
            while(fraction > 1.0) fraction = fraction / 10.0;
 
192
            total += fraction;
 
193
        }
 
194
    }
 
195
 
 
196
    /* parse optional units */
 
197
    if (GetToken() == XmtLexerKeyword) {
 
198
        XmtLayoutUnitType units;
 
199
 
 
200
        switch(GetKeyword()) {
 
201
        case INCHES:  units = XmtLayoutInches;  break;
 
202
        case MILLIMETERS: units =  XmtLayoutMillimeters; break;
 
203
        case POINTS: units =  XmtLayoutPoints; break;
 
204
        case EMS: units =  XmtLayoutEms; break;
 
205
        case ENS: units = XmtLayoutEns; break;
 
206
        default:  return (int) total;
 
207
        }
 
208
 
 
209
        ConsumeToken();
 
210
        return XmtLayoutConvertSizeToPixels((Widget)lw, total, units);
 
211
    }
 
212
 
 
213
    return (int) total;
 
214
}
 
215
 
 
216
#if NeedFunctionPrototypes
 
217
static void ParseSpace(XmtLayoutWidget lw, XmtLayoutLocalInfo *li)
 
218
#else
 
219
static void ParseSpace(lw, li)
 
220
XmtLayoutWidget lw;
 
221
XmtLayoutLocalInfo *li;
 
222
#endif
 
223
{
 
224
    switch(GetKeyword()) {
 
225
    case EVEN:
 
226
    case EVENSPACED:
 
227
        li->space_type = XmtLayoutSpaceEven;
 
228
        break;
 
229
    case LREVENSPACED:
 
230
        li->space_type = XmtLayoutSpaceLREven;
 
231
        break;
 
232
    case INTERVALSPACED:
 
233
        li->space_type = XmtLayoutSpaceInterval;
 
234
        break;
 
235
    case LCRSPACED:
 
236
        li->space_type = XmtLayoutSpaceLCR;
 
237
        break;
 
238
    case LTABBED:
 
239
        li->space_type = XmtLayoutSpaceLTabbed;
 
240
        break;
 
241
    case CTABBED:
 
242
        li->space_type = XmtLayoutSpaceCTabbed;
 
243
        break;
 
244
    case RTABBED:
 
245
        li->space_type = XmtLayoutSpaceRTabbed;
 
246
        break;
 
247
    }
 
248
 
 
249
    if (NextToken() == XmtLexerInteger)
 
250
        li->space = ParsePixelSize(lw);
 
251
 
 
252
    if (GetToken() == XmtLexerPlus) {
 
253
        if (NextToken() != XmtLexerInteger)
 
254
            XmtWarningMsg("XmtLayout", "space0",
 
255
                          "Widget '%s':\n\tinteger expected following '+' in space specification",
 
256
                          XtName((Widget)lw));
 
257
        else{
 
258
            li->space_stretch = GetIntValue();
 
259
 
 
260
            if (NextToken() == XmtLexerSlash) {
 
261
                if (NextToken() != XmtLexerInteger)
 
262
                    XmtWarningMsg("XmtLayout", "space1",
 
263
                                  "Widget '%s':\n\tinteger expected following '/' in space specification",
 
264
                                  XtName((Widget)lw));
 
265
                else {
 
266
                    li->item_stretch = GetIntValue();
 
267
                    ConsumeToken();
 
268
                }
 
269
            }
 
270
        }
 
271
    }
 
272
}
 
273
 
 
274
#if NeedFunctionPrototypes
 
275
static void ParseCaption(XmtLayoutWidget lw, XmtLayoutInfo *i)
 
276
#else
 
277
static void ParseCaption(lw, i)
 
278
XmtLayoutWidget lw;
 
279
XmtLayoutInfo *i;
 
280
#endif
 
281
{
 
282
    String args;
 
283
 
 
284
    ConsumeToken();
 
285
    if (GetToken() == XmtLexerIdent) {
 
286
        args = GetStrValue();
 
287
 
 
288
        if (args[0]) {
 
289
            i->dummy_constraints.caption_position = 1;
 
290
            switch(args[0]) {
 
291
            case 'l':
 
292
                i->constraints.caption_position = XmtLayoutLeft;
 
293
                break;
 
294
            case 'r':
 
295
                i->constraints.caption_position = XmtLayoutRight;
 
296
                break;
 
297
            case 't':
 
298
                i->constraints.caption_position = XmtLayoutTop;
 
299
                break;
 
300
            case 'b':
 
301
                i->constraints.caption_position = XmtLayoutBottom;
 
302
                break;
 
303
            default:
 
304
                XmtWarningMsg("XmtLayout", "caption0",
 
305
                              "Widget '%s':Unknown caption position '%c' in layout string.\n\tl, r, t, or b expected.",
 
306
                              XtName((Widget)lw), args[0]);     
 
307
                i->dummy_constraints.caption_position = 0;
 
308
                break;
 
309
            }
 
310
        }
 
311
 
 
312
        if (args[0] && args[1]) {
 
313
            i->dummy_constraints.caption_justification = 1;
 
314
            switch(args[1]) {
 
315
            case 'l':
 
316
            case 't':
 
317
                i->constraints.caption_justification=XmtLayoutFlushLeft;
 
318
                break;
 
319
            case 'r':
 
320
            case 'b':
 
321
                i->constraints.caption_justification=XmtLayoutFlushRight;
 
322
                break;
 
323
            case 'c':
 
324
                i->constraints.caption_justification=XmtLayoutCentered;
 
325
                break;
 
326
            default:
 
327
                XmtWarningMsg("XmtLayout", "caption1",
 
328
                              "Widget '%s':Unknown caption justification '%c' in layout string.\n\tl, r, t, b, or c expected.",
 
329
                              XtName((Widget)lw), args[1]);
 
330
                i->dummy_constraints.caption_justification = 0;
 
331
                break;
 
332
            }
 
333
        }
 
334
 
 
335
        if (args[0] && args[1] && args[2]) {
 
336
            i->dummy_constraints.caption_alignment = 1;
 
337
            switch(args[2]) {
 
338
            case 'l':
 
339
                i->constraints.caption_alignment = XmALIGNMENT_BEGINNING;
 
340
                break;
 
341
            case 'r':
 
342
                i->constraints.caption_alignment = XmALIGNMENT_END;
 
343
                break;
 
344
            case 'c':
 
345
                i->constraints.caption_alignment = XmALIGNMENT_CENTER;
 
346
                break;
 
347
            default:
 
348
                XmtWarningMsg("XmtLayout", "caption2",
 
349
                              "Widget '%s': Unknown caption alignment '%c' in layout string.\n\tl, r, or c expected.",
 
350
                              XtName((Widget)lw), args[2]);
 
351
                i->dummy_constraints.caption_alignment = 0;
 
352
                break;
 
353
            }
 
354
        }
 
355
        
 
356
        XtFree(args);
 
357
        ConsumeToken();
 
358
    }
 
359
 
 
360
    if (GetToken() == XmtLexerInteger) {
 
361
        i->dummy_constraints.caption_margin = 1;
 
362
        i->constraints.caption_margin = GetIntValue();
 
363
        ConsumeToken();
 
364
    }
 
365
 
 
366
    if (GetToken() == XmtLexerString) {
 
367
        i->dummy_constraints.caption = (XmString)1;
 
368
        i->constraints.caption = XmtCreateLocalizedXmString((Widget) lw, GetStrValue());
 
369
        i->constraints.dont_copy_caption = 1;
 
370
        XtFree(GetStrValue());
 
371
        ConsumeToken();
 
372
    }
 
373
    else
 
374
        XmtWarningMsg("XmtLayout", "caption3",
 
375
                      "Widget '%s': string expected following 'Caption' keyword.",
 
376
                      XtName((Widget)lw));
 
377
}
 
378
 
 
379
#if NeedFunctionPrototypes
 
380
static void ParseMargin(XmtLayoutWidget lw, XmtLayoutInfo *i)
 
381
#else
 
382
static void ParseMargin(lw, i)
 
383
XmtLayoutWidget lw;
 
384
XmtLayoutInfo *i;
 
385
#endif
 
386
{
 
387
    Boolean width = True;
 
388
    Boolean height = True;
 
389
 
 
390
    ConsumeToken();
 
391
    if (GetToken() == XmtLexerKeyword){
 
392
        if (GetKeyword() == WIDTH) height = False;
 
393
        else if (GetKeyword() == HEIGHT) width = False;
 
394
        else goto error;
 
395
        ConsumeToken();
 
396
    }
 
397
 
 
398
    if (GetToken() == XmtLexerInteger) {
 
399
        if (width) {
 
400
            i->dummy_constraints.margin_width = 1;
 
401
            i->constraints.margin_width = GetIntValue();
 
402
        }
 
403
        if (height) {
 
404
            i->dummy_constraints.margin_height = 1;
 
405
            i->constraints.margin_height = GetIntValue();
 
406
        }
 
407
        ConsumeToken();
 
408
    }
 
409
    else
 
410
        goto error;
 
411
 
 
412
    return;
 
413
 
 
414
 error:
 
415
    XmtWarningMsg("XmtLayout", "margin",
 
416
                  "Widget '%s':\n\t'Width', 'Height', or integer expected following 'Margin' keyword.",
 
417
                  XtName((Widget)lw));
 
418
}
 
419
 
 
420
#if NeedFunctionPrototypes
 
421
static void ParseFrame(XmtLayoutWidget lw, XmtLayoutInfo *i)
 
422
#else
 
423
static void ParseFrame(lw, i)
 
424
XmtLayoutWidget lw;
 
425
XmtLayoutInfo *i;
 
426
#endif
 
427
{
 
428
    int type, linetype;
 
429
 
 
430
    i->dummy_constraints.frame_line_type = 1;
 
431
    i->dummy_constraints.frame_type = 1;
 
432
    type = XmtLayoutFrameBox;
 
433
    
 
434
    switch(GetKeyword()) {
 
435
    case SHADOWED: linetype = XmtLayoutFrameShadowIn; break;
 
436
    default:
 
437
    case ETCHED:   linetype = XmtLayoutFrameEtchedIn; break;
 
438
    case LINE:
 
439
    case BOXED:    linetype = XmtLayoutFrameSingleLine; break;
 
440
    case DOUBLELINE:
 
441
    case DOUBLEBOXED: linetype = XmtLayoutFrameDoubleLine; break;
 
442
    }
 
443
    ConsumeToken();
 
444
 
 
445
    if (GetToken() == XmtLexerKeyword) {
 
446
        if (GetKeyword() == OUT) {
 
447
            if (linetype == XmtLayoutFrameShadowIn)
 
448
                linetype = XmtLayoutFrameShadowOut;
 
449
            else if (linetype == XmtLayoutFrameEtchedIn)
 
450
                linetype = XmtLayoutFrameEtchedOut;
 
451
            ConsumeToken();
 
452
        }
 
453
        else if (GetKeyword() == IN) ConsumeToken();
 
454
    }
 
455
    i->constraints.frame_line_type = linetype;
 
456
    
 
457
    if (GetToken() == XmtLexerKeyword) {
 
458
        switch(GetKeyword()) {
 
459
        case LEFT:
 
460
            type = XmtLayoutFrameLeft; break;
 
461
        case RIGHT:
 
462
            type = XmtLayoutFrameRight; break;
 
463
        case TOP:
 
464
            type = XmtLayoutFrameTop; break;
 
465
        case BOTTOM:
 
466
            type = XmtLayoutFrameBottom; break;
 
467
        }
 
468
        if (type != XmtLayoutFrameBox) ConsumeToken();
 
469
    }
 
470
 
 
471
    i->constraints.frame_type = type;
 
472
 
 
473
    if (GetToken() == XmtLexerKeyword) {
 
474
        i->dummy_constraints.frame_position = 1;
 
475
        if (GetKeyword() == INSIDE)
 
476
            i->constraints.frame_position = XmtLayoutFrameInside;
 
477
        else if (GetKeyword() == OUTSIDE)
 
478
            i->constraints.frame_position = XmtLayoutFrameOutside;
 
479
        else if (GetKeyword() == THROUGH)
 
480
            i->constraints.frame_position = XmtLayoutFrameThrough;
 
481
        else
 
482
            i->dummy_constraints.frame_position = 0;
 
483
 
 
484
        if (i->dummy_constraints.frame_position) ConsumeToken();
 
485
    }
 
486
 
 
487
    if (GetToken() == XmtLexerInteger) {
 
488
        i->dummy_constraints.frame_margin = 1;
 
489
        i->constraints.frame_margin = GetIntValue();
 
490
        ConsumeToken();
 
491
        if (GetToken() == XmtLexerInteger) {
 
492
            i->dummy_constraints.frame_thickness = 1;
 
493
            i->constraints.frame_thickness = GetIntValue();
 
494
            ConsumeToken();
 
495
        }
 
496
    }
 
497
}
 
498
 
 
499
 
 
500
#if NeedFunctionPrototypes
 
501
static void ParseModifiers(XmtLayoutWidget lw,
 
502
                           XmtLayoutInfo *i, XmtLayoutLocalInfo *li)
 
503
#else
 
504
static void ParseModifiers(lw, i, li)
 
505
XmtLayoutWidget lw;
 
506
XmtLayoutInfo *i;
 
507
XmtLayoutLocalInfo *li;
 
508
#endif
 
509
{
 
510
    XmtLexerToken tok; 
 
511
    int size;
 
512
 
 
513
    for(;;) {
 
514
        tok = GetToken();
 
515
        if ((tok == XmtLexerInteger) || (tok == XmtLexerPeriod)) {
 
516
            size = ParsePixelSize(lw);
 
517
 
 
518
            if ((GetToken() == XmtLexerKeyword) &&
 
519
                ((GetKeyword() == WIDE) || (GetKeyword() == HIGH))) {
 
520
                if (GetKeyword() == WIDE) {
 
521
                    i->dummy_constraints.width = 1;
 
522
                    i->constraints.width = size;
 
523
                    ConsumeToken();
 
524
                }
 
525
                else if (GetKeyword() == HIGH) {
 
526
                    i->dummy_constraints.height = 1;
 
527
                    i->constraints.height = size;
 
528
                    ConsumeToken();
 
529
                }
 
530
            }
 
531
            else if (GetToken() == XmtLexerPercent) {
 
532
                i->dummy_constraints.width = 1;
 
533
                i->constraints.width = size;
 
534
                ConsumeToken();
 
535
                if (GetToken() == XmtLexerInteger) {
 
536
                    i->dummy_constraints.height = 1;
 
537
                    i->constraints.height = ParsePixelSize(lw);
 
538
                }
 
539
                else XmtWarningMsg("XmtLayout", "size",
 
540
                               "%s: number must follow '%%' in layout string.",
 
541
                                   XtName((Widget)lw));
 
542
            }
 
543
            else { /* a size alone is always assumed to be  a width */
 
544
                i->dummy_constraints.width = 1;
 
545
                i->constraints.width = size;
 
546
            }
 
547
        }
 
548
        else if (tok == XmtLexerPlus) {
 
549
            ConsumeToken();
 
550
            if ((GetToken() == XmtLexerInteger) ||
 
551
                (GetToken() == XmtLexerPeriod)) {
 
552
                i->dummy_constraints.stretchability = 1;
 
553
                i->constraints.stretchability = ParsePixelSize(lw);
 
554
            }
 
555
            else XmtWarningMsg("XmtLayout", "stretch",
 
556
                               "%s: number must follow '+' in layout string.",
 
557
                               XtName((Widget)lw));
 
558
        }
 
559
        else if (tok == XmtLexerMinus) {
 
560
            ConsumeToken();
 
561
            if ((GetToken() == XmtLexerInteger) ||
 
562
                (GetToken() == XmtLexerPeriod)) {
 
563
                i->dummy_constraints.shrinkability = 1;
 
564
                i->constraints.shrinkability = ParsePixelSize(lw);
 
565
            }
 
566
            else XmtWarningMsg("XmtLayout", "shrink",
 
567
                               "%s: number must follow '-' in layout string.",
 
568
                               XtName((Widget)lw));
 
569
        }
 
570
        else if (tok == XmtLexerKeyword) {
 
571
            Boolean dont_consume = False;
 
572
            switch(GetKeyword()) {
 
573
            case FIXED: 
 
574
                i->dummy_constraints.stretchability = 1;
 
575
                i->dummy_constraints.shrinkability = 1;
 
576
                i->constraints.stretchability = 0;
 
577
                i->constraints.shrinkability = 0;
 
578
                break;
 
579
            case STRETCHABLE:
 
580
                i->dummy_constraints.stretchability = 1;
 
581
                i->dummy_constraints.shrinkability = 1;
 
582
                i->constraints.stretchability = INFINITY;
 
583
                i->constraints.shrinkability = INFINITY;
 
584
                break;
 
585
            case CAPTION:
 
586
                ParseCaption(lw, i);
 
587
                dont_consume = True;
 
588
                break;
 
589
            case SHADOWED: 
 
590
            case ETCHED:
 
591
            case BOXED:
 
592
            case DOUBLEBOXED:
 
593
            case LINE:
 
594
            case DOUBLELINE:
 
595
                ParseFrame(lw,i);
 
596
                dont_consume = True;
 
597
                break;
 
598
            case MARGIN: 
 
599
                ParseMargin(lw, i);
 
600
                dont_consume = True;
 
601
                break;
 
602
            case EQUAL:
 
603
                li->equal = True;
 
604
                break;
 
605
            case EVEN:
 
606
            case EVENSPACED:
 
607
            case LREVENSPACED:
 
608
            case INTERVALSPACED:
 
609
            case LCRSPACED:
 
610
            case LTABBED:
 
611
            case CTABBED:
 
612
            case RTABBED:
 
613
                ParseSpace(lw, li);
 
614
                dont_consume = True;
 
615
                break;
 
616
            case UNMANAGED:
 
617
                li->unmanaged = True;
 
618
                break;
 
619
            case FILLED:
 
620
                i->dummy_constraints.justification = 1;
 
621
                i->constraints.justification = XmtLayoutFilled;
 
622
                break;
 
623
            case CENTERED:
 
624
                i->dummy_constraints.justification = 1;
 
625
                i->constraints.justification = XmtLayoutCentered;
 
626
                break;
 
627
            case FLUSHLEFT:
 
628
            case FLUSHTOP:
 
629
                i->dummy_constraints.justification = 1;
 
630
                i->constraints.justification = XmtLayoutFlushLeft;
 
631
                break;
 
632
            case FLUSHRIGHT:
 
633
            case FLUSHBOTTOM:
 
634
                i->dummy_constraints.justification = 1;
 
635
                i->constraints.justification = XmtLayoutFlushRight;
 
636
                break;
 
637
            case UNRESIZABLE:
 
638
                i->dummy_constraints.allow_resize = 1;
 
639
                i->constraints.allow_resize = False;
 
640
                break;
 
641
            case COLOR:
 
642
                ConsumeToken();
 
643
                if (GetToken() != XmtLexerString) {
 
644
                    XmtWarningMsg("XmtLayout", "color",
 
645
                                "%s: color name expected after Color keyword.",
 
646
                                  XtName((Widget)lw));
 
647
                }
 
648
                else {
 
649
                    XrmValue from, to;
 
650
                    from.addr = GetStrValue();
 
651
                    from.size = GetStrLength()+1;
 
652
                    to.addr = (XPointer) &li->color;
 
653
                    to.size = sizeof(Pixel);
 
654
                    if (XtConvertAndStore((Widget)lw,
 
655
                                          XtRString, &from, XtRPixel, &to))
 
656
                        li->color_set = True;
 
657
                    XtFree(GetStrValue());
 
658
                    ConsumeToken();
 
659
                }
 
660
                dont_consume = True;
 
661
                break;
 
662
            default:
 
663
                return;
 
664
            }
 
665
            if (!dont_consume) ConsumeToken();
 
666
        }
 
667
        else return;
 
668
    }
 
669
}
 
670
    
 
671
 
 
672
#if NeedFunctionPrototypes
 
673
static void GetArgList(XmtLayoutInfo *i, XmtLayoutLocalInfo *li,
 
674
                       WidgetClass wclass, ArgList al, Cardinal *count)
 
675
#else
 
676
static void GetArgList(i, li, wclass, al, count)
 
677
XmtLayoutInfo *i;
 
678
XmtLayoutLocalInfo *li;
 
679
WidgetClass wclass;
 
680
ArgList al;
 
681
Cardinal *count;
 
682
#endif
 
683
{
 
684
    Cardinal ac = *count;
 
685
 
 
686
#define SetArg(resource, field)\
 
687
    if (i->dummy_constraints.field) {\
 
688
        XtSetArg(al[ac], resource, i->constraints.field);\
 
689
        ac++;\
 
690
    }
 
691
 
 
692
    SetArg(XmtNlayoutWidth, width);
 
693
    SetArg(XmtNlayoutHeight, height);
 
694
    SetArg(XmtNlayoutStretchability, stretchability);
 
695
    SetArg(XmtNlayoutShrinkability, shrinkability);
 
696
    SetArg(XmtNlayoutAllowResize, allow_resize);
 
697
    SetArg(XmtNlayoutJustification, justification);
 
698
    SetArg(XmtNlayoutMarginWidth, margin_width);
 
699
    SetArg(XmtNlayoutMarginHeight, margin_height);
 
700
    SetArg(XmtNlayoutFrameType, frame_type);
 
701
    SetArg(XmtNlayoutFrameLineType, frame_line_type);
 
702
    SetArg(XmtNlayoutFramePosition, frame_position);
 
703
    SetArg(XmtNlayoutFrameMargin, frame_margin);
 
704
    SetArg(XmtNlayoutFrameThickness, frame_thickness);
 
705
    SetArg(XmtNlayoutCaption, caption);
 
706
    SetArg(XmtNlayoutCaptionPosition, caption_position);
 
707
    SetArg(XmtNlayoutCaptionJustification, caption_justification);
 
708
    SetArg(XmtNlayoutCaptionAlignment, caption_alignment);
 
709
    SetArg(XmtNlayoutCaptionMargin, caption_margin);
 
710
#undef SetArg
 
711
 
 
712
    if (wclass == xmtLayoutBoxGadgetClass) {
 
713
        if (li->equal) {
 
714
            XtSetArg(al[ac], XmtNequal, True); ac++;
 
715
        }
 
716
        
 
717
        if (li->space_type != XmtLayoutSpaceNone) {
 
718
            XtSetArg(al[ac], XmtNspaceType, li->space_type); ac++;
 
719
        }
 
720
 
 
721
        if (li->space != 0) {
 
722
            XtSetArg(al[ac], XmtNspace, li->space); ac++;
 
723
        }
 
724
 
 
725
        if (li->space_stretch != 1) {
 
726
            XtSetArg(al[ac], XmtNspaceStretch, li->space_stretch); ac++;
 
727
        }
 
728
 
 
729
        if (li->item_stretch != 1) {
 
730
            XtSetArg(al[ac], XmtNitemStretch, li->item_stretch);
 
731
            ac++;
 
732
        }
 
733
    }
 
734
 
 
735
 
 
736
    if (li->color_set) {
 
737
        if (wclass == xmtLayoutBoxGadgetClass)
 
738
            XtSetArg(al[ac], XmtNbackground, li->color);
 
739
        else
 
740
            XtSetArg(al[ac], XmtNforeground, li->color);
 
741
        ac++;
 
742
    }
 
743
    
 
744
    *count = ac;
 
745
}
 
746
 
 
747
#if NeedFunctionPrototypes
 
748
static void ParseName(XmtLayoutWidget lw, XmtLayoutInfo *i)
 
749
#else
 
750
static void ParseName(lw, i)
 
751
XmtLayoutWidget lw;
 
752
XmtLayoutInfo *i;
 
753
#endif
 
754
{
 
755
    if (GetToken() == XmtLexerIdent) {
 
756
        i->name = XrmStringToQuark(GetStrValue());
 
757
        XtFree(GetStrValue());
 
758
        ConsumeToken();
 
759
    }
 
760
}    
 
761
 
 
762
#if NeedFunctionPrototypes
 
763
static Boolean ParseItem(XmtLayoutWidget lw, Widget container)
 
764
#else
 
765
static Boolean ParseItem(lw, container)
 
766
XmtLayoutWidget lw;
 
767
Widget container;
 
768
#endif
 
769
{
 
770
    XmtLexerToken tok = GetToken();
 
771
    XmtLayoutInfo *i;
 
772
    XmtLayoutLocalInfo li;
 
773
    WidgetClass wclass;
 
774
    int j;
 
775
    Arg al[30];
 
776
    Cardinal ac;
 
777
    Boolean named_child = False;
 
778
    XtPointer child_type = NULL;
 
779
    String child_name = NULL;
 
780
    String label = NULL;
 
781
    Boolean is_bitmap;
 
782
    
 
783
    if ((tok == XmtLexerEndOfString) || (tok == XmtLexerError)) return False;
 
784
 
 
785
    i = (XmtLayoutInfo *) XtCalloc(1, sizeof(XmtLayoutInfo));
 
786
 
 
787
    /* set "local info" field to their defaults */
 
788
    li.unmanaged = False;
 
789
    li.equal = False;
 
790
    li.color_set = False;
 
791
    li.space_type = XmtLayoutSpaceNone;
 
792
    li.space = 0;
 
793
    li.space_stretch = 1;
 
794
    li.item_stretch = 1;
 
795
 
 
796
    /*
 
797
     * any item can have any modifiers, though some are overridden or ignored
 
798
     */
 
799
    ParseModifiers(lw, i, &li);
 
800
    wclass = NULL;
 
801
    ac = 0;
 
802
    tok = GetToken();
 
803
 
 
804
    switch(tok) {
 
805
    case XmtLexerBar:
 
806
    ParseVSep:
 
807
        ConsumeToken();
 
808
        wclass = xmtLayoutSeparatorGadgetClass;
 
809
        XtSetArg(al[ac], XmtNorientation, XmVERTICAL); ac++;
 
810
        break;
 
811
    case XmtLexerEqual:
 
812
    ParseHSep:
 
813
        ConsumeToken();
 
814
        wclass = xmtLayoutSeparatorGadgetClass;
 
815
        XtSetArg(al[ac], XmtNorientation, XmHORIZONTAL); ac++;
 
816
        break;
 
817
    case XmtLexerString:
 
818
    ParseString:
 
819
        wclass = xmtLayoutStringGadgetClass;
 
820
        label = GetStrValue();
 
821
        XtSetArg(al[ac], XmtNlabel, label); ac++;
 
822
        ConsumeToken();
 
823
        break;
 
824
    case XmtLexerSharp:
 
825
        wclass = xmtLayoutSpaceGadgetClass;
 
826
        ConsumeToken();
 
827
        for(j=1; GetToken() == XmtLexerSharp; j++) ConsumeToken();
 
828
        i->constraints.width = i->constraints.height =
 
829
            j*lw->layout.default_spacing;
 
830
        i->constraints.stretchability = 0;
 
831
        i->constraints.shrinkability = 0;
 
832
        i->dummy_constraints.width = i->dummy_constraints.height = 1;
 
833
        i->dummy_constraints.stretchability = 1;
 
834
        i->dummy_constraints.shrinkability = 1;
 
835
        break;
 
836
    case XmtLexerTwiddle:
 
837
        wclass = xmtLayoutSpaceGadgetClass;
 
838
        ConsumeToken();
 
839
        for(j=1; GetToken() == XmtLexerTwiddle; j++) ConsumeToken();
 
840
        i->constraints.width = 0;
 
841
        i->constraints.height = 0;
 
842
        i->constraints.stretchability = j*XmtLAYOUT_DEFAULT_STRETCHABILITY;
 
843
        i->constraints.shrinkability = 0;
 
844
        i->dummy_constraints.width = i->dummy_constraints.height = 1;
 
845
        i->dummy_constraints.stretchability = 1;
 
846
        i->dummy_constraints.shrinkability = 1;
 
847
        break;
 
848
    case XmtLexerLess:
 
849
        ConsumeToken();
 
850
        for(j=1; GetToken() == XmtLexerMinus; j++) ConsumeToken();
 
851
        if (GetToken() != XmtLexerGreater)
 
852
            XmtWarningMsg("XmtLayout", "greater",
 
853
                          "%s: '>' expected after '<' in layout string.",
 
854
                          XtName((Widget)lw));
 
855
        else
 
856
            ConsumeToken();
 
857
        wclass = xmtLayoutSpaceGadgetClass;
 
858
        i->constraints.width = 0;
 
859
        i->constraints.height = 0;
 
860
        i->constraints.stretchability = j*INFINITY;
 
861
        i->constraints.shrinkability = 0;
 
862
        i->dummy_constraints.width = i->dummy_constraints.height = 1;
 
863
        i->dummy_constraints.stretchability = 1;
 
864
        i->dummy_constraints.shrinkability = 1;
 
865
        break;
 
866
    case XmtLexerIdent:
 
867
        /* get type and name to create, or just a name */
 
868
        if ((xmtLayoutClassRec.layout_class.lookup_type_proc) &&
 
869
            (child_type = (*xmtLayoutClassRec.layout_class.lookup_type_proc)
 
870
             (GetStrValue()))) {
 
871
            XtFree(GetStrValue());
 
872
            ConsumeToken();
 
873
            if (GetToken() != XmtLexerIdent) {
 
874
                XmtWarningMsg("XmtLayout", "create",
 
875
                              "Widget '%s':\n\twidget name expected following widget type in layout string.",
 
876
                              XtName((Widget)lw));
 
877
                goto error;
 
878
            }
 
879
            else {
 
880
                child_name = GetStrValue();
 
881
                ConsumeToken();
 
882
            }
 
883
        }
 
884
        else {
 
885
            named_child = True;       /* a child that will be created later */
 
886
            i->name = XrmStringToQuark(GetStrValue());
 
887
            XtFree(GetStrValue());
 
888
            ConsumeToken();
 
889
        }
 
890
        break;
 
891
    case XmtLexerKeyword:
 
892
        switch (GetKeyword()) {
 
893
        case ROW:
 
894
            wclass = xmtLayoutBoxGadgetClass;
 
895
            ConsumeToken();
 
896
            ParseName(lw, i);
 
897
            XtSetArg(al[ac], XmtNorientation, XmHORIZONTAL); ac++;
 
898
            break;
 
899
        case COL:
 
900
            wclass = xmtLayoutBoxGadgetClass;
 
901
            ConsumeToken();
 
902
            ParseName(lw, i);
 
903
            XtSetArg(al[ac], XmtNorientation, XmVERTICAL); ac++;
 
904
            break;
 
905
        case SPACE:
 
906
            wclass = xmtLayoutSpaceGadgetClass;
 
907
            ConsumeToken();
 
908
            break;
 
909
        case HSEP:
 
910
            goto ParseHSep;
 
911
        case VSEP:
 
912
            goto ParseVSep;
 
913
        case STRING:  /* string keyword, not XmtLexerString token */
 
914
            ConsumeToken();
 
915
            ParseName(lw, i);
 
916
            if (GetToken() != XmtLexerString) {
 
917
                XmtWarningMsg("XmtLayout", "string",
 
918
                              "%s: string must follow String keyword",
 
919
                              XtName((Widget)lw));
 
920
            }
 
921
            else
 
922
                goto ParseString;
 
923
            break;
 
924
        case BITMAP:
 
925
        case PIXMAP:
 
926
            if (GetKeyword() == PIXMAP) is_bitmap = False;
 
927
            else is_bitmap = True;
 
928
            wclass = xmtLayoutPixmapGadgetClass;
 
929
            ConsumeToken();
 
930
            ParseName(lw, i);
 
931
            if (GetToken() != XmtLexerString) {
 
932
                XmtWarningMsg("XmtLayout", "pixmap",
 
933
                           "%s: string must follow Pixmap or Bitmap keyword.",
 
934
                              XtName((Widget)lw));
 
935
            }
 
936
            else {
 
937
                XrmValue from, to;
 
938
                from.addr = GetStrValue();
 
939
                from.size = GetStrLength()+1;
 
940
                al[ac].name = (is_bitmap)?XmtNbitmap:XmtNpixmap;
 
941
                to.addr = (XPointer) &al[ac].value;
 
942
                to.size = sizeof(Pixel);
 
943
                if (XtConvertAndStore((Widget)lw,
 
944
                                   XtRString, &from,
 
945
                                   (is_bitmap)?XtRBitmap:XtRPixmap,
 
946
                                   &to))
 
947
                    ac++;
 
948
                XtFree(GetStrValue());
 
949
                ConsumeToken();
 
950
 
 
951
                /*
 
952
                 * Now, look for ` , "mask_name"' to set the XmtNbitmask
 
953
                 * resource
 
954
                 */
 
955
                if (GetToken() == XmtLexerComma) {
 
956
                    if (NextToken() != XmtLexerString) {
 
957
                        XmtWarningMsg("XmtLayout", "pixmap",
 
958
                                      "%s: mask name must follow comma in Pixmap or Bitmap specification.",
 
959
                                      XtName((Widget)lw));
 
960
                    }
 
961
                    else {
 
962
                        XrmValue from, to;
 
963
                        from.addr = GetStrValue();
 
964
                        from.size = GetStrLength()+1;
 
965
                        al[ac].name = XmtNbitmask;
 
966
                        to.addr = (XPointer) &al[ac].value;
 
967
                        to.size = sizeof(Pixel);
 
968
                        if (XtConvertAndStore((Widget)lw,
 
969
                                              XtRString, &from,
 
970
                                              XmtRBitmask,
 
971
                                              &to))
 
972
                            ac++;
 
973
                        XtFree(GetStrValue());
 
974
                        ConsumeToken();
 
975
                    }
 
976
                }
 
977
            }
 
978
            break;
 
979
        default:
 
980
            XmtWarningMsg("XmtLayout", "keyword",
 
981
                          "Widget %s:\n\tunexpected keyword '%s' in layout string.",
 
982
                          XtName((Widget)lw), GetStrValue());
 
983
            ConsumeToken();
 
984
            goto error;
 
985
        }
 
986
        break;
 
987
    case XmtLexerEndOfString:
 
988
        XmtWarningMsg("XmtLayout", "end",
 
989
                      "%s: unexpected end of layout string.",
 
990
                      XtName((Widget)lw));
 
991
        goto error;
 
992
    default:
 
993
        XmtWarningMsg("XmtLayout", "syntax",
 
994
                      "%s: syntax error in layout string.",XtName((Widget)lw));
 
995
        ConsumeToken();
 
996
        goto error;
 
997
    }
 
998
 
 
999
    if (named_child) {  /* a widget to be created later */
 
1000
        Widget marker;
 
1001
 
 
1002
        /* create a gadget to mark the position of the widget */
 
1003
        marker = XtVaCreateWidget("", xmtLayoutSpaceGadgetClass, (Widget)lw,
 
1004
                                  XmtNlayoutIn, container, NULL);
 
1005
 
 
1006
        /* store the constraint info away for later lookup */
 
1007
        /* this is special; we don't set dummy_constraints */
 
1008
        i->constraints.after = marker;
 
1009
        i->next = lw->layout.widget_info;
 
1010
        lw->layout.widget_info = i;
 
1011
    }
 
1012
    else {  /* a typed widget or a layout gadget to create now */
 
1013
        Widget w = NULL;
 
1014
        
 
1015
        /* set position arg, get constraint args, and create the child */
 
1016
        XtSetArg(al[ac], XmtNlayoutIn, container); ac++;
 
1017
        GetArgList(i, &li, wclass, al, &ac);
 
1018
        if (child_type) {
 
1019
            w = (*xmtLayoutClassRec.layout_class.create_proc)
 
1020
                (child_name, child_type, (Widget)lw, al, ac);
 
1021
            XtFree(child_name);
 
1022
        }
 
1023
        else if (wclass != NULL)
 
1024
            w = XtCreateWidget((i->name)?XrmQuarkToString(i->name):"",
 
1025
                               wclass, (Widget)lw, al, ac);
 
1026
        
 
1027
        /* if it is a row or column, parse its children */
 
1028
        if (wclass == xmtLayoutBoxGadgetClass) {  /* a row or column */
 
1029
            if (GetToken() != XmtLexerLBrace) {
 
1030
                XmtWarningMsg("XmtLayout", "open",
 
1031
                              "%s: '{' expected at beginning of row.",
 
1032
                              XtName((Widget)lw));
 
1033
            }
 
1034
            else {
 
1035
                ConsumeToken();
 
1036
                while ((tok = GetToken())) {
 
1037
                    if ((tok == XmtLexerRBrace) || (tok == XmtLexerError) ||
 
1038
                        (tok == XmtLexerEndOfString)) break;
 
1039
                    if (!ParseItem(lw, w)) {
 
1040
                        /* error recovery: read till '}' or end of string */
 
1041
                        while(tok != XmtLexerEndOfString &&
 
1042
                              tok != XmtLexerRBrace)
 
1043
                            tok = NextToken();
 
1044
                        break;
 
1045
                    }
 
1046
                }
 
1047
            }
 
1048
 
 
1049
            if (GetToken() != XmtLexerRBrace) {
 
1050
                XmtWarningMsg("XmtLayout", "close",
 
1051
                              "%s: '}' expected at end of row.",
 
1052
                              XtName((Widget)lw));
 
1053
            }
 
1054
            else ConsumeToken();
 
1055
        }
 
1056
 
 
1057
        /* manage it unless specified otherwise */
 
1058
        if (w && !li.unmanaged) XtManageChild(w);
 
1059
 
 
1060
        /* free our info structure */
 
1061
        XtFree((char *)i);
 
1062
    }
 
1063
    if (label) XtFree(label);
 
1064
    return True;
 
1065
 
 
1066
 error:
 
1067
    if (i->constraints.caption) XmStringFree(i->constraints.caption);
 
1068
    XtFree((char *)i);
 
1069
    if (label) XtFree(label);
 
1070
    return False;
 
1071
}
 
1072
 
 
1073
#if NeedFunctionPrototypes
 
1074
static void XmtLayoutParse(XmtLayoutWidget lw, String str)
 
1075
#else
 
1076
static void XmtLayoutParse(lw, str)
 
1077
XmtLayoutWidget lw;
 
1078
String str;
 
1079
#endif
 
1080
{
 
1081
    XmtLexerToken tok;
 
1082
    
 
1083
    lw->layout.lexer = XmtLexerCreate(keywords, XtNumber(keywords));
 
1084
    XmtLexerInit(lw->layout.lexer, str);
 
1085
 
 
1086
    while(1) {
 
1087
        tok = GetToken();
 
1088
        if ((tok == XmtLexerEndOfString)  || (tok == XmtLexerError)) break;
 
1089
        /* NULL means place items in the toplevel container */
 
1090
        if (!ParseItem(lw, NULL)) break;
 
1091
    }
 
1092
 
 
1093
    if (tok == XmtLexerError)
 
1094
        XmtWarningMsg("XmtLayout", "syntax", "%s: syntax error.",
 
1095
                      XtName((Widget)lw));
 
1096
 
 
1097
    XmtLexerDestroy(lw->layout.lexer);
 
1098
}
 
1099
 
 
1100
#if NeedFunctionPrototypes
 
1101
void XmtRegisterLayoutParser(void)
 
1102
#else
 
1103
void XmtRegisterLayoutParser()
 
1104
#endif
 
1105
{
 
1106
    xmtLayoutClassRec.layout_class.parser = XmtLayoutParse;
 
1107
}