~ubuntu-branches/ubuntu/karmic/grace/karmic

« back to all changes in this revision

Viewing changes to Xbae/Xbae/Shadow.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2002-03-19 14:19:58 UTC
  • Revision ID: james.westby@ubuntu.com-20020319141958-5gxna6vo1ek3zjml
Tags: upstream-5.1.7
ImportĀ upstreamĀ versionĀ 5.1.7

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) 1995-99 Andrew Lister
 
4
 *                        All rights reserved
 
5
 * Permission to use, copy, modify and distribute this material for
 
6
 * any purpose and without fee is hereby granted, provided that the
 
7
 * above copyright notice and this permission notice appear in all
 
8
 * copies, and that the name of Bellcore not be used in advertising
 
9
 * or publicity pertaining to this material without the specific,
 
10
 * prior written permission of an authorized representative of
 
11
 * Bellcore.
 
12
 *
 
13
 * BELLCORE MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES, EX-
 
14
 * PRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
 
15
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 
16
 * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST IN-
 
17
 * FRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS.  THE
 
18
 * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL BELLCORE OR
 
19
 * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
 
20
 * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELAT-
 
21
 * ING TO THE SOFTWARE.
 
22
 *
 
23
 * $Id: Shadow.c,v 1.1 1999/09/11 01:25:38 fnevgeny Exp $
 
24
 */
 
25
 
 
26
 
 
27
/*
 
28
 * Shadow.c created by Andrew Lister (30 October, 1995)
 
29
 */
 
30
 
 
31
 
 
32
#ifdef HAVE_CONFIG_H
 
33
#include <config.h>
 
34
#endif
 
35
 
 
36
#include <Xm/Xm.h>
 
37
#include <Xm/XmP.h>
 
38
#if XmVersion > 1001
 
39
#include <Xm/DrawP.h>
 
40
#endif
 
41
#include <Xbae/MatrixP.h>
 
42
#include <Xbae/Shadow.h>
 
43
#include <Xbae/Draw.h>
 
44
#include <Xbae/Utils.h>
 
45
 
 
46
static void DrawRowShadow P((XbaeMatrixWidget, Window, int, int, int,
 
47
                             int, int, int, GC, GC));
 
48
 
 
49
static void DrawColumnShadow P((XbaeMatrixWidget, Window, int, int, int,
 
50
                                int, int, int, GC, GC));
 
51
 
 
52
static void DrawRowHighlight P((XbaeMatrixWidget, Window, GC, int, int,
 
53
                                 int, int, int, int, int));
 
54
static void DrawColumnHighlight P((XbaeMatrixWidget, Window, GC, int,
 
55
                                    int, int, int, int, int, int));
 
56
 
 
57
void
 
58
#if NeedFunctionPrototypes
 
59
xbaeDrawCellShadow(XbaeMatrixWidget mw, Window win, int row, int column, int x,
 
60
                   int y, int width, int height, Boolean label,
 
61
                   Boolean clipped, Boolean pressed)
 
62
#else
 
63
xbaeDrawCellShadow(mw, win, row, column, x, y, width, height, label, clipped,
 
64
                   pressed)
 
65
XbaeMatrixWidget mw;
 
66
Window win;
 
67
int row;
 
68
int column;
 
69
int x;
 
70
int y;
 
71
int width;
 
72
int height;
 
73
Boolean label;
 
74
Boolean clipped;
 
75
Boolean pressed;
 
76
#endif
 
77
{
 
78
    unsigned char grid_type;
 
79
    unsigned char shadow;
 
80
    
 
81
    if ((mw->matrix.cell_shadow_thickness == 0) &&
 
82
        (!IN_GRID_ROW_MODE(mw)) && (!IN_GRID_COLUMN_MODE(mw)))
 
83
        return;
 
84
 
 
85
    /*
 
86
     * Surround the cell with a shadow.
 
87
     */
 
88
    if(label)
 
89
    {
 
90
        shadow = pressed ? XmSHADOW_IN : XmSHADOW_OUT;
 
91
        grid_type = XmGRID_CELL_SHADOW;
 
92
    }
 
93
    else
 
94
    {
 
95
        shadow = mw->matrix.cell_shadow_types ?
 
96
            mw->matrix.cell_shadow_types[row][column] :
 
97
            mw->matrix.cell_shadow_type;
 
98
        grid_type = mw->matrix.grid_type;
 
99
    }
 
100
        
 
101
    if (clipped)
 
102
    {
 
103
        switch (grid_type)
 
104
        {
 
105
            case XmGRID_CELL_SHADOW:
 
106
                DRAW_SHADOW(XtDisplay(mw), win,
 
107
                            mw->matrix.cell_top_shadow_clip_gc,
 
108
                            mw->matrix.cell_bottom_shadow_clip_gc,
 
109
                            mw->matrix.cell_shadow_thickness,
 
110
                            x, y, width, height, shadow);
 
111
                break;
 
112
 
 
113
            /* Deprecated types. To be removed in next version. */
 
114
            case XmGRID_SHADOW_OUT:
 
115
                DRAW_SHADOW(XtDisplay(mw), win,
 
116
                            mw->matrix.cell_bottom_shadow_clip_gc,
 
117
                            mw->matrix.cell_top_shadow_clip_gc,
 
118
                            mw->matrix.cell_shadow_thickness,
 
119
                            x, y, width, height, shadow);
 
120
                break;
 
121
            case XmGRID_SHADOW_IN:
 
122
                DRAW_SHADOW(XtDisplay(mw), win,
 
123
                            mw->matrix.cell_top_shadow_clip_gc,
 
124
                            mw->matrix.cell_bottom_shadow_clip_gc,
 
125
                            mw->matrix.cell_shadow_thickness,
 
126
                            x, y, width, height, shadow);
 
127
                break;
 
128
        }
 
129
    }
 
130
    else
 
131
    {
 
132
        switch (grid_type)
 
133
        {
 
134
        case XmGRID_NONE:
 
135
            break;
 
136
        case XmGRID_ROW_SHADOW:
 
137
            DrawRowShadow(mw, win, row, column, x, y, width, height,
 
138
                          mw->manager.top_shadow_GC,
 
139
                          mw->manager.bottom_shadow_GC);
 
140
            break;
 
141
        case XmGRID_ROW_LINE:
 
142
            DrawRowShadow(mw, win, row, column, x, y, width, height,
 
143
                          mw->matrix.grid_line_gc, mw->matrix.grid_line_gc);
 
144
            break;
 
145
        case XmGRID_COLUMN_SHADOW:
 
146
            DrawColumnShadow(mw, win, row, column, x, y, width, height,
 
147
                             mw->manager.top_shadow_GC,
 
148
                             mw->manager.bottom_shadow_GC);
 
149
            break;
 
150
        case XmGRID_COLUMN_LINE:
 
151
            DrawColumnShadow(mw, win, row, column, x, y, width, height,
 
152
                             mw->matrix.grid_line_gc, mw->matrix.grid_line_gc);
 
153
            break;
 
154
        case XmGRID_CELL_LINE:
 
155
            DRAW_SHADOW(XtDisplay(mw), win,
 
156
                        mw->matrix.grid_line_gc,
 
157
                        mw->matrix.grid_line_gc,
 
158
                        mw->matrix.cell_shadow_thickness,
 
159
                        x, y, width, height, shadow);
 
160
            break;
 
161
        case XmGRID_CELL_SHADOW:
 
162
            DRAW_SHADOW(XtDisplay(mw), win,
 
163
                        mw->manager.top_shadow_GC,
 
164
                        mw->manager.bottom_shadow_GC,
 
165
                        mw->matrix.cell_shadow_thickness,
 
166
                        x, y, width, height, shadow);
 
167
            break;
 
168
 
 
169
        /* Deprecated types. To be removed in next version. */
 
170
        case XmGRID_LINE:
 
171
            DRAW_SHADOW(XtDisplay(mw), win,
 
172
                        mw->matrix.grid_line_gc,
 
173
                        mw->matrix.grid_line_gc,
 
174
                        mw->matrix.cell_shadow_thickness,
 
175
                        x, y, width, height, shadow);
 
176
            break;
 
177
        case XmGRID_SHADOW_OUT:
 
178
            DRAW_SHADOW(XtDisplay(mw), win,
 
179
                        mw->manager.bottom_shadow_GC,
 
180
                        mw->manager.top_shadow_GC,
 
181
                        mw->matrix.cell_shadow_thickness,
 
182
                        x, y, width, height, shadow);
 
183
            break;
 
184
        case XmGRID_SHADOW_IN:
 
185
            DRAW_SHADOW(XtDisplay(mw), win,
 
186
                        mw->manager.top_shadow_GC,
 
187
                        mw->manager.bottom_shadow_GC,
 
188
                        mw->matrix.cell_shadow_thickness,
 
189
                        x, y, width, height, shadow);
 
190
            break;
 
191
        }
 
192
    }    
 
193
}
 
194
 
 
195
#if XmVersion >= 1002
 
196
void
 
197
xbaeDrawCellHighlight(mw, win, gc, row, column, x, y, width, height, reason)
 
198
XbaeMatrixWidget mw;
 
199
Window win;
 
200
GC gc;
 
201
int row;
 
202
int column;
 
203
int x;
 
204
int y;
 
205
int width;
 
206
int height;
 
207
int reason;
 
208
{    
 
209
    int thick;
 
210
 
 
211
    if (!mw->matrix.highlighted_cells) /* Just a precaution */
 
212
        return;
 
213
 
 
214
    if (!mw->matrix.highlighted_cells[row][column])
 
215
        return;                 /* Nothing to do! */
 
216
 
 
217
    if (reason & HIGHLIGHTING_SOMETHING)
 
218
        gc = mw->manager.highlight_GC;
 
219
 
 
220
    if (IN_GRID_ROW_MODE(mw) &&
 
221
        (reason & HighlightRow || reason & UnhighlightRow) &&
 
222
        mw->matrix.highlighted_cells[row][column] == HighlightRow)
 
223
        DrawRowHighlight(mw, win, gc, row, column, x, y, width, height,
 
224
                         reason);
 
225
    else if (IN_GRID_COLUMN_MODE(mw) &&
 
226
             (reason & HighlightColumn || reason & UnhighlightColumn) &&
 
227
        mw->matrix.highlighted_cells[row][column] == HighlightColumn)
 
228
        DrawColumnHighlight(mw, win, gc, row, column, x, y, width, height,
 
229
                            reason);
 
230
    else
 
231
    {
 
232
        thick = (2 * mw->matrix.cell_shadow_thickness);
 
233
 
 
234
        DRAW_HIGHLIGHT(XtDisplay(mw), win, gc,
 
235
                        x + mw->matrix.cell_shadow_thickness,
 
236
                        y + mw->matrix.cell_shadow_thickness,
 
237
                        width - thick, height - thick,
 
238
                        mw->matrix.cell_highlight_thickness,
 
239
                        LineSolid);
 
240
    }
 
241
}
 
242
 
 
243
static void
 
244
DrawRowHighlight(mw, win, gc, row, column, x, y, width, height, reason)
 
245
XbaeMatrixWidget mw;
 
246
Window win;
 
247
GC gc;
 
248
int row;
 
249
int column;
 
250
int x;
 
251
int y;
 
252
int width;
 
253
int height;
 
254
int reason;
 
255
{    
 
256
    XRectangle rect[1];
 
257
    
 
258
    rect[0].x = 0;
 
259
    rect[0].y = 0;
 
260
    rect[0].width = width;
 
261
    rect[0].height = height;
 
262
 
 
263
    XSetClipRectangles(XtDisplay(mw), gc, x, y, rect, 1, Unsorted);
 
264
 
 
265
    y += mw->matrix.cell_shadow_thickness;
 
266
    height -= 2 * mw->matrix.cell_shadow_thickness;
 
267
 
 
268
    if (column != mw->matrix.columns - 1)
 
269
    {
 
270
        if (column != 0)
 
271
            x -= (mw->matrix.cell_shadow_thickness +
 
272
                mw->matrix.cell_highlight_thickness);
 
273
        else
 
274
            x += mw->matrix.cell_shadow_thickness;
 
275
        DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, mw->core.width, height,
 
276
                        mw->matrix.cell_highlight_thickness,
 
277
                        LineSolid);
 
278
    }
 
279
    else
 
280
    {
 
281
        if (NEED_HORIZ_FILL(mw))
 
282
            width = mw->core.width;
 
283
        
 
284
        x -= (mw->matrix.cell_shadow_thickness +
 
285
              mw->matrix.cell_highlight_thickness);
 
286
        width += mw->matrix.cell_highlight_thickness;
 
287
 
 
288
        DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, width,
 
289
                        height, mw->matrix.cell_highlight_thickness,
 
290
                        LineSolid);
 
291
 
 
292
        if (NEED_HORIZ_FILL(mw))
 
293
        {
 
294
            int ax, ay;
 
295
 
 
296
            xbaeCalcHorizFill(mw, win, x, y, row, column, &ax, &ay,
 
297
                              &width, &height);
 
298
            rect[0].width = width;
 
299
            rect[0].height = height;
 
300
            XSetClipRectangles(XtDisplay(mw), gc, ax, ay, rect, 1,
 
301
                               Unsorted);
 
302
            height -= mw->matrix.cell_shadow_thickness * 2;
 
303
            ax -= mw->matrix.cell_highlight_thickness;
 
304
            width += (mw->matrix.cell_highlight_thickness -
 
305
                      mw->matrix.cell_shadow_thickness);
 
306
                
 
307
            DRAW_HIGHLIGHT(XtDisplay(mw), XtWindow(mw), gc, ax, ay,
 
308
                            width, height,
 
309
                            mw->matrix.cell_highlight_thickness,
 
310
                            LineSolid);
 
311
        }
 
312
    }
 
313
    XSetClipMask(XtDisplay(mw), gc, None);
 
314
}
 
315
 
 
316
static void
 
317
DrawColumnHighlight(mw, win, gc, row, column, x, y, width, height, reason)
 
318
XbaeMatrixWidget mw;
 
319
Window win;
 
320
GC gc;
 
321
int row;
 
322
int column;
 
323
int x;
 
324
int y;
 
325
int width;
 
326
int height;
 
327
int reason;
 
328
{    
 
329
    XRectangle rect[1];
 
330
    int vert_dead_space_height = VERT_DEAD_SPACE_HEIGHT(mw);
 
331
    int clip_vert_visible_space = CLIP_VERT_VISIBLE_SPACE(mw);
 
332
    int vert_sb_height = VERT_SB_HEIGHT(mw);
 
333
    Boolean need_vert_dead_space_fill = NEED_VERT_DEAD_SPACE_FILL(mw);
 
334
 
 
335
    /* This adjustment takes care of that little open area
 
336
     * between the last nonfixed row and the first trailing
 
337
     * fixed row when the matrix is smaller than its max height */
 
338
    if ((vert_dead_space_height == 0) &&
 
339
        ((TRAILING_VERT_ORIGIN(mw) - 1) == row) &&
 
340
        (vert_sb_height < clip_vert_visible_space))
 
341
        height += (mw->matrix.cell_shadow_thickness +
 
342
                    clip_vert_visible_space - vert_sb_height);
 
343
 
 
344
    rect[0].x = 0;
 
345
    rect[0].y = 0;
 
346
    rect[0].width = width;
 
347
    rect[0].height = height;
 
348
 
 
349
    XSetClipRectangles(XtDisplay(mw), gc, x, y, rect, 1, Unsorted);
 
350
 
 
351
    x += mw->matrix.cell_shadow_thickness;
 
352
    width -= 2 * mw->matrix.cell_shadow_thickness;
 
353
 
 
354
    if (row != mw->matrix.rows - 1)
 
355
    {
 
356
        if (row != 0)
 
357
            y -= (mw->matrix.cell_shadow_thickness +
 
358
                  mw->matrix.cell_highlight_thickness);
 
359
        else
 
360
            y += mw->matrix.cell_shadow_thickness;
 
361
        DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, width, mw->core.height,
 
362
                        mw->matrix.cell_highlight_thickness,
 
363
                        LineSolid);
 
364
    }
 
365
    else
 
366
    {
 
367
        if (NEED_VERT_FILL(mw) && (! HAS_ATTACHED_TRAILING_ROWS(mw)))
 
368
            height = mw->core.height;
 
369
        else
 
370
            height += mw->matrix.cell_highlight_thickness;
 
371
        
 
372
        y -= (mw->matrix.cell_shadow_thickness +
 
373
              mw->matrix.cell_highlight_thickness);
 
374
        
 
375
        DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, width,
 
376
                        height, mw->matrix.cell_highlight_thickness,
 
377
                        LineSolid);
 
378
 
 
379
        if (NEED_VERT_FILL(mw) || need_vert_dead_space_fill)
 
380
        {
 
381
            int ax, ay;
 
382
 
 
383
            xbaeCalcVertFill(mw, win, x, y, row, column, &ax, &ay,
 
384
                             &width, &height);
 
385
            
 
386
            /* If we're filling the dead space, then we only use
 
387
             * the width and ax from above call. */
 
388
            if (need_vert_dead_space_fill)
 
389
            {
 
390
                ay = UNATTACHED_TRAILING_ROWS_OFFSET(mw);
 
391
                height = mw->matrix.cell_shadow_thickness +
 
392
                    mw->matrix.cell_highlight_thickness +
 
393
                    vert_dead_space_height;
 
394
            }
 
395
 
 
396
            rect[0].width = width;
 
397
            rect[0].height = height;
 
398
            XSetClipRectangles(XtDisplay(mw), gc, ax, ay, rect, 1,
 
399
                               Unsorted);
 
400
            width -= mw->matrix.cell_shadow_thickness * 2;
 
401
            ay -= mw->matrix.cell_highlight_thickness;
 
402
            height += (mw->matrix.cell_highlight_thickness -
 
403
                       mw->matrix.cell_shadow_thickness);
 
404
                
 
405
            /* Make sure height extends past bottom clip */
 
406
            if (need_vert_dead_space_fill && IS_FIXED_COLUMN(mw, column))
 
407
                height += (mw->matrix.cell_shadow_thickness +
 
408
                           mw->matrix.cell_highlight_thickness);
 
409
 
 
410
            DRAW_HIGHLIGHT(XtDisplay(mw), XtWindow(mw), gc, ax, ay,
 
411
                            width, height,
 
412
                            mw->matrix.cell_highlight_thickness,
 
413
                            LineSolid);
 
414
        }
 
415
    }
 
416
    XSetClipMask(XtDisplay(mw), gc, None);
 
417
}
 
418
 
 
419
#endif
 
420
 
 
421
static void
 
422
DrawRowShadow(mw, win, row, column, x, y, width, height, topGC, bottomGC)
 
423
XbaeMatrixWidget mw;
 
424
Window win;
 
425
int row;
 
426
int column;
 
427
int x;
 
428
int y;
 
429
int width;
 
430
int height;
 
431
GC  topGC;
 
432
GC  bottomGC;
 
433
{
 
434
    XRectangle rect[1];
 
435
    unsigned char shadow = mw->matrix.row_shadow_types ?
 
436
        mw->matrix.row_shadow_types[row] : mw->matrix.cell_shadow_type;
 
437
 
 
438
    rect[0].x = 0;
 
439
    rect[0].y = 0;
 
440
    rect[0].width = width;
 
441
    rect[0].height = height;
 
442
 
 
443
    /*
 
444
     * Set up the clipping rectangle to be only over the current cell
 
445
     */
 
446
    XSetClipRectangles(XtDisplay(mw),
 
447
                       topGC,
 
448
                       x, y, rect, 1, Unsorted);
 
449
    if (topGC != bottomGC)
 
450
        XSetClipRectangles(XtDisplay(mw),
 
451
                           bottomGC,
 
452
                           x, y, rect, 1, Unsorted);
 
453
    /*
 
454
     * Now, convert our coordinates to what we need to draw
 
455
     */
 
456
    if (column != mw->matrix.columns - 1)
 
457
    {
 
458
        /*
 
459
         * If column is 0, then we need to show the left hand side of the
 
460
         * box, otherwise just draw the edges outside the clipping rectangle
 
461
         */
 
462
        width = mw->core.width;
 
463
        if (column != 0)
 
464
            x -= mw->matrix.cell_shadow_thickness;
 
465
 
 
466
        DRAW_SHADOW(XtDisplay(mw), win,
 
467
                    topGC, bottomGC,
 
468
                    mw->matrix.cell_shadow_thickness,
 
469
                    x, y, width, height, shadow);
 
470
    }
 
471
    else
 
472
    {
 
473
        if (NEED_HORIZ_FILL(mw))
 
474
            /*
 
475
             * If we are going to fill, the right hand side of the shadow
 
476
             * shouldn't be drawn - we'll do it later!
 
477
             */
 
478
            width = mw->core.width;
 
479
        else
 
480
            width += mw->matrix.cell_shadow_thickness;
 
481
 
 
482
        DRAW_SHADOW(XtDisplay(mw), win,
 
483
                    topGC, bottomGC,
 
484
                    mw->matrix.cell_shadow_thickness,
 
485
                    x - mw->matrix.cell_shadow_thickness, y, width,
 
486
                    height, shadow);
 
487
 
 
488
        if (NEED_HORIZ_FILL(mw))
 
489
        {
 
490
            /*
 
491
             * The filled part is drawn on the matrix's window so we need to
 
492
             * do a bit of extra work.
 
493
             */
 
494
            int ax, ay;
 
495
 
 
496
            xbaeCalcHorizFill(mw, win, x, y, row, column, &ax, &ay,
 
497
                              &width, &height);
 
498
            
 
499
            rect[0].width = width;
 
500
            rect[0].height = height;
 
501
 
 
502
            XSetClipRectangles(XtDisplay(mw),
 
503
                               topGC,
 
504
                               ax, ay, rect, 1, Unsorted);
 
505
            if (topGC != bottomGC)
 
506
                XSetClipRectangles(XtDisplay(mw),
 
507
                                   bottomGC,
 
508
                                   ax, ay, rect, 1, Unsorted);
 
509
            
 
510
            /*
 
511
             * Final tweaks. Note that these _cannot_ be part of the calc
 
512
             * horiz fill logic, since that is used to set the clipping
 
513
             * rectangle
 
514
             */
 
515
 
 
516
            if ((win == XtWindow(ClipChild(mw))) &&
 
517
                (height != ROW_HEIGHT(mw)))
 
518
            {
 
519
                if (height == (ClipChild(mw)->core.height +
 
520
                               ClipChild(mw)->core.y - ay))
 
521
                    height += mw->matrix.cell_shadow_thickness;
 
522
 
 
523
                if (ay == ClipChild(mw)->core.y)
 
524
                {
 
525
                    height += mw->matrix.cell_shadow_thickness;
 
526
                    ay -= mw->matrix.cell_shadow_thickness;
 
527
                }
 
528
            }
 
529
 
 
530
            /* Do same check for RightClip. Now, why this is even
 
531
             * necessary when we're drawing on the Matrix's window,
 
532
             * I dunno. This one is only necessary when
 
533
             * we've got trailing fixed columns. */
 
534
            if (mw->matrix.trailing_fixed_columns &&
 
535
                (win == XtWindow(RightClip(mw))) &&
 
536
                (height != ROW_HEIGHT(mw)))
 
537
            {
 
538
                if (height == (RightClip(mw)->core.height +
 
539
                               RightClip(mw)->core.y - ay))
 
540
                    height += mw->matrix.cell_shadow_thickness;
 
541
 
 
542
                if (ay == RightClip(mw)->core.y)
 
543
                {
 
544
                    height += mw->matrix.cell_shadow_thickness;
 
545
                    ay -= mw->matrix.cell_shadow_thickness;
 
546
                }
 
547
            }
 
548
            
 
549
            /*
 
550
             * Draw the remaining shadow directly onto the matrix window
 
551
             */
 
552
            DRAW_SHADOW(XtDisplay(mw), XtWindow(mw),
 
553
                        topGC, bottomGC,
 
554
                        mw->matrix.cell_shadow_thickness,
 
555
                        ax - mw->matrix.cell_shadow_thickness,
 
556
                        ay, width + mw->matrix.cell_shadow_thickness,
 
557
                        height, shadow);
 
558
        }
 
559
    }
 
560
    /*
 
561
     * Reset our GC's clip mask
 
562
     */
 
563
    XSetClipMask(XtDisplay(mw), topGC,
 
564
                 None);
 
565
    if (topGC != bottomGC)
 
566
        XSetClipMask(XtDisplay(mw), bottomGC,
 
567
                     None);
 
568
}
 
569
 
 
570
static void
 
571
DrawColumnShadow(mw, win, row, column, x, y, width, height, topGC, bottomGC)
 
572
XbaeMatrixWidget mw;
 
573
Window win;
 
574
int row;
 
575
int column;
 
576
int x;
 
577
int y;
 
578
int width;
 
579
int height;
 
580
GC  topGC;
 
581
GC  bottomGC;
 
582
{
 
583
    XRectangle rect[1];
 
584
    unsigned char shadow = mw->matrix.column_shadow_types ?
 
585
        mw->matrix.column_shadow_types[column] : mw->matrix.cell_shadow_type;
 
586
    int vert_dead_space_height = VERT_DEAD_SPACE_HEIGHT(mw);
 
587
    int clip_vert_visible_space = CLIP_VERT_VISIBLE_SPACE(mw);
 
588
    int vert_sb_height = VERT_SB_HEIGHT(mw);
 
589
    Boolean need_vert_dead_space_fill = NEED_VERT_DEAD_SPACE_FILL(mw);
 
590
 
 
591
    /* This adjustment takes care of that little open area
 
592
     * between the last nonfixed row and the first trailing
 
593
     * fixed row when the matrix is smaller than its max height */
 
594
    if ((vert_dead_space_height == 0) &&
 
595
        ((TRAILING_VERT_ORIGIN(mw) - 1) == row) &&
 
596
        (vert_sb_height < clip_vert_visible_space))
 
597
        height += (mw->matrix.cell_shadow_thickness +
 
598
                    clip_vert_visible_space - vert_sb_height);
 
599
 
 
600
    rect[0].x = 0;
 
601
    rect[0].y = 0;
 
602
    rect[0].width = width;
 
603
    rect[0].height = height;
 
604
 
 
605
    /*
 
606
     * Set up the clipping rectangle to be only over the current cell
 
607
     */
 
608
    XSetClipRectangles(XtDisplay(mw),
 
609
                       topGC,
 
610
                       x, y, rect, 1, Unsorted);
 
611
    if (topGC != bottomGC)
 
612
        XSetClipRectangles(XtDisplay(mw),
 
613
                           bottomGC,
 
614
                           x, y, rect, 1, Unsorted);
 
615
    /*
 
616
     * Now, convert our coordinates to what we need to draw
 
617
     */
 
618
    if (row != mw->matrix.rows - 1)
 
619
    {
 
620
        /*
 
621
         * If column is 0, then we need to show the left hand side of the
 
622
         * box, otherwise just draw the edges outside the clipping rectangle
 
623
         */
 
624
        height = mw->core.height;
 
625
        if (row != 0)
 
626
            y -= mw->matrix.cell_shadow_thickness;
 
627
 
 
628
        DRAW_SHADOW(XtDisplay(mw), win,
 
629
                    topGC, bottomGC,
 
630
                    mw->matrix.cell_shadow_thickness,
 
631
                    x, y, width, height, shadow);
 
632
    }
 
633
    else
 
634
    {
 
635
        if (NEED_VERT_FILL(mw) && (! HAS_ATTACHED_TRAILING_ROWS(mw)))
 
636
            /*
 
637
             * If we are going to fill, the bottom of the shadow
 
638
             * shouldn't be drawn
 
639
             */
 
640
            height = mw->core.height;
 
641
        else
 
642
            height += mw->matrix.cell_shadow_thickness;
 
643
 
 
644
        DRAW_SHADOW(XtDisplay(mw), win,
 
645
                    topGC, bottomGC,
 
646
                    mw->matrix.cell_shadow_thickness,
 
647
                    x, y - mw->matrix.cell_shadow_thickness,
 
648
                    width, height, shadow);
 
649
 
 
650
        /*
 
651
         * The filled part is drawn on the matrix's window so we need to
 
652
         * do a bit of extra work. We may need to fill either the entire
 
653
         * bottom portion of the matrix, or the dead space, that is, the
 
654
         * space between the last nonfixed row and the first trailing
 
655
         * fixed row. We only need to do the latter case when we've got
 
656
         * bottom attached trailing fixed rows with vertical dead space
 
657
         * (vertical dead space only occurs when the matrix is bigger
 
658
         * than its maximum height, i.e., we're filling).
 
659
         */
 
660
        if (NEED_VERT_FILL(mw) || need_vert_dead_space_fill)
 
661
        {
 
662
            int ax, ay;
 
663
            
 
664
            xbaeCalcVertFill(mw, win, x, y, row, column, &ax, &ay,
 
665
                             &width, &height);
 
666
 
 
667
            /* If we're filling the dead space, then we only use
 
668
             * the width and ax from above call. */
 
669
            if (need_vert_dead_space_fill)
 
670
            {
 
671
                ay = UNATTACHED_TRAILING_ROWS_OFFSET(mw);
 
672
                height = mw->matrix.cell_shadow_thickness +
 
673
                    vert_dead_space_height;
 
674
            }
 
675
 
 
676
            rect[0].width = width;
 
677
            rect[0].height = height;
 
678
 
 
679
            XSetClipRectangles(XtDisplay(mw),
 
680
                               topGC,
 
681
                               ax, ay, rect, 1, Unsorted);
 
682
            if (topGC != bottomGC)
 
683
                XSetClipRectangles(XtDisplay(mw),
 
684
                                   bottomGC,
 
685
                                   ax, ay, rect, 1, Unsorted);
 
686
 
 
687
            /*
 
688
             * Final tweaks. Note that these _cannot_ be part of the
 
689
             * calc vert fill logic, since that is used to set the
 
690
             * clipping rectangle
 
691
             */
 
692
            
 
693
            if ((win == XtWindow(ClipChild(mw))) &&
 
694
                (width != COLUMN_WIDTH(mw, column)))
 
695
            {
 
696
                /* Make sure we don't draw a shadow along the matrix's
 
697
                 * shadow by extending our width past the edge of the
 
698
                 * clipping rectangle
 
699
                 */
 
700
                if (width == (ClipChild(mw)->core.width +
 
701
                              ClipChild(mw)->core.x - ax))
 
702
                    width += mw->matrix.cell_shadow_thickness;
 
703
 
 
704
                /*
 
705
                 * Make sure the shadow doesn't get drawn along the left
 
706
                 * side by moving the x pos outside the clipping
 
707
                 * rectangle.
 
708
                 */
 
709
                if (ax == ClipChild(mw)->core.x)
 
710
                {
 
711
                    width += mw->matrix.cell_shadow_thickness;
 
712
                    ax -= mw->matrix.cell_shadow_thickness;
 
713
                }
 
714
            }
 
715
 
 
716
            /*
 
717
             * Do same check for BottomClip. Now, why this is even
 
718
             * necessary when we're drawing on the Matrix's window,
 
719
             * I dunno. This one is only necessary when we've got
 
720
             * trailing fixed rows.
 
721
             */
 
722
            if (mw->matrix.trailing_fixed_rows &&
 
723
                (win == XtWindow(BottomClip(mw))) &&
 
724
                (width != COLUMN_WIDTH(mw, column)))
 
725
            {
 
726
                if (width == (BottomClip(mw)->core.width +
 
727
                              BottomClip(mw)->core.x - ax))
 
728
                    width += mw->matrix.cell_shadow_thickness;
 
729
 
 
730
                if (ax == BottomClip(mw)->core.x)
 
731
                {
 
732
                    width += mw->matrix.cell_shadow_thickness;
 
733
                    ax -= mw->matrix.cell_shadow_thickness;
 
734
                }
 
735
            }
 
736
 
 
737
            /* Make sure height extends past bottom clip */
 
738
            if (need_vert_dead_space_fill && IS_FIXED_COLUMN(mw, column))
 
739
                height += mw->matrix.cell_shadow_thickness;
 
740
 
 
741
            /*
 
742
             * Draw the remaining shadow directly onto the matrix window
 
743
             */
 
744
            DRAW_SHADOW(XtDisplay(mw), XtWindow(mw),
 
745
                        topGC, bottomGC,
 
746
                        mw->matrix.cell_shadow_thickness,
 
747
                        ax, ay - mw->matrix.cell_shadow_thickness,
 
748
                        width, height + mw->matrix.cell_shadow_thickness,
 
749
                        shadow);
 
750
        }
 
751
    }
 
752
 
 
753
    /*
 
754
     * Reset our GC's clip mask
 
755
     */
 
756
    XSetClipMask(XtDisplay(mw), topGC,
 
757
                 None);
 
758
    if (topGC != bottomGC)
 
759
        XSetClipMask(XtDisplay(mw), bottomGC,
 
760
                     None);
 
761
}