1 /*
2  * Copyright(c) 1992 Bell Communications Research, Inc. (Bellcore)
3  * Copyright(c) 1995-99 Andrew Lister
4  * Copyright � 1999, 2000, 2001, 2002, 2003, 2004 by the LessTif Developers.
5  *
6  *                        All rights reserved
7  * Permission to use, copy, modify and distribute this material for
8  * any purpose and without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies, and that the name of Bellcore not be used in advertising
11  * or publicity pertaining to this material without the specific,
12  * prior written permission of an authorized representative of
13  * Bellcore.
14  *
15  * BELLCORE MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES, EX-
16  * PRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
17  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18  * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST IN-
19  * FRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS.  THE
20  * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL BELLCORE OR
21  * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
22  * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELAT-
23  * ING TO THE SOFTWARE.
24  *
25  * $Id: Shadow.c,v 1.29 2005/04/06 23:13:14 tobiasoed Exp $
26  */
27 
28 /*
29  * Shadow.c created by Andrew Lister (30 October, 1995)
30  */
31 
32 
33 #ifdef HAVE_CONFIG_H
34 #include <XbaeConfig.h>
35 #endif
36 
37 #include <stdio.h>
38 
39 #include <Xm/Xm.h>
40 #include <Xm/XmP.h>
41 #include <Xm/DrawP.h>
42 #include <Xbae/MatrixP.h>
43 #include <Xbae/Shadow.h>
44 #include <Xbae/Draw.h>
45 #include <Xbae/Utils.h>
46 
47 #include <XbaeDebug.h>
48 
49 static void DrawRowShadow(XbaeMatrixWidget, Window, int, int, int, int, int, int, GC, GC, unsigned char shadow);
50 static void DrawColumnShadow(XbaeMatrixWidget, Window, int, int, int, int, int, int, GC, GC, unsigned char shadow);
51 
52 static void DrawRowHighlight(XbaeMatrixWidget, Window, GC, int, int, int, int, int, int);
53 static void DrawColumnHighlight(XbaeMatrixWidget, Window, GC, int, int, int, int, int, int);
54 
55 void
xbaeDrawLabelShadow(XbaeMatrixWidget mw,Window win,int x,int y,int width,int height,Boolean pressed)56 xbaeDrawLabelShadow(XbaeMatrixWidget mw, Window win, int x, int y, int width, int height,
57                     Boolean pressed)
58 {
59         if (mw->matrix.cell_shadow_thickness == 0) {
60                 return;
61         }
62 
63         /*
64          * Surround the label with a shadow.
65          */
66 
67         DRAW_SHADOW(XtDisplay(mw), win, "win",
68                     mw->manager.top_shadow_GC, mw->manager.bottom_shadow_GC,
69                     mw->matrix.cell_shadow_thickness, x, y, width, height,
70                     pressed ? XmSHADOW_IN : XmSHADOW_OUT);
71 }
72 
73 void
xbaeDrawCellShadow(XbaeMatrixWidget mw,Window win,int row,int column,int x,int y,int width,int height)74 xbaeDrawCellShadow(XbaeMatrixWidget mw, Window win, int row, int column, int x, int y, int width, int height)
75 {
76         GC top_shadow_gc = mw->manager.top_shadow_GC;
77         GC bottom_shadow_gc = mw->manager.bottom_shadow_GC;
78         GC grid_line_gc = mw->matrix.grid_line_gc;
79 
80         unsigned char shadow = mw->matrix.cell_shadow_type;
81         unsigned char grid_type = mw->matrix.grid_type;
82 
83 /* amai, that's too verbose ...*/
84         DEBUGOUT(_XbaeDebug
85                  (__FILE__, (Widget) mw, "xbaeDrawCellShadow [%d,%d] wid %d, ht %d\n", row, column,
86                   width, height));
87 
88         if (mw->matrix.cell_shadow_thickness == 0) {
89                 return;
90         }
91 
92         if (mw->matrix.per_cell && mw->matrix.per_cell[row][column].shadow_type != 0) {
93                 shadow = mw->matrix.per_cell[row][column].shadow_type;
94                 grid_type = XmGRID_CELL_SHADOW;
95         } else if (IN_GRID_ROW_MODE(mw) && mw->matrix.row_shadow_types && mw->matrix.row_shadow_types[row] != 0) {
96                 shadow = mw->matrix.row_shadow_types[row];
97                 grid_type = XmGRID_ROW_SHADOW;
98         } else if (IN_GRID_COLUMN_MODE(mw) && mw->matrix.column_shadow_types && mw->matrix.column_shadow_types[column] != 0) {
99                 shadow = mw->matrix.column_shadow_types[column];
100                 grid_type = XmGRID_COLUMN_SHADOW;
101         }
102 
103         /*
104          * Surround the cell with a shadow.
105          */
106         switch (grid_type) {
107         case XmGRID_NONE:
108                 break;
109         case XmGRID_ROW_SHADOW:
110                 DrawRowShadow(mw, win, row, column, x, y, width, height,
111                               top_shadow_gc, bottom_shadow_gc, shadow);
112                 break;
113         case XmGRID_ROW_LINE:
114                 DrawRowShadow(mw, win, row, column, x, y, width, height,
115                               grid_line_gc, grid_line_gc, shadow);
116                 break;
117         case XmGRID_COLUMN_SHADOW:
118                 DrawColumnShadow(mw, win, row, column, x, y, width, height,
119                                  top_shadow_gc, bottom_shadow_gc, shadow);
120                 break;
121         case XmGRID_COLUMN_LINE:
122                 DrawColumnShadow(mw, win, row, column, x, y, width, height,
123                                  grid_line_gc, grid_line_gc, shadow);
124                 break;
125         case XmGRID_CELL_LINE:
126                 DRAW_SHADOW(XtDisplay(mw), win, "win",
127                             grid_line_gc, grid_line_gc,
128                             mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
129                 break;
130         case XmGRID_CELL_SHADOW:
131                 DRAW_SHADOW(XtDisplay(mw), win, "win",
132                             top_shadow_gc, bottom_shadow_gc,
133                             mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
134                 break;
135 
136                 /* Deprecated types. To be removed in next version. */
137         case XmGRID_LINE:
138                 DRAW_SHADOW(XtDisplay(mw), win, "win",
139                             grid_line_gc, grid_line_gc,
140                             mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
141                 break;
142         case XmGRID_SHADOW_OUT:
143                 DRAW_SHADOW(XtDisplay(mw), win, "win",
144                             bottom_shadow_gc, top_shadow_gc,
145                             mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
146                 break;
147         case XmGRID_SHADOW_IN:
148                 DRAW_SHADOW(XtDisplay(mw), win, "win",
149                             top_shadow_gc, bottom_shadow_gc,
150                             mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
151                 break;
152         }
153 }
154 
155 void
xbaeDrawCellHighlight(XbaeMatrixWidget mw,Window win,GC gc,int row,int column,int x,int y,int width,int height,unsigned char hl)156 xbaeDrawCellHighlight(XbaeMatrixWidget mw, Window win, GC gc, int row, int column,
157                       int x, int y, int width, int height, unsigned char hl)
158 {
159         int thick = mw->matrix.cell_shadow_thickness;
160 
161         DEBUGOUT(_XbaeDebug
162                  (__FILE__, (Widget) mw, "xbaeDrawCellHighlight [%d,%d], wid %d, ht %d\n", row,
163                   column, width, height));
164 
165         if (IN_GRID_ROW_MODE(mw) && (hl & HighlightRow)) {
166                 DrawRowHighlight(mw, win, gc, row, column, x, y, width, height);
167         } else if (IN_GRID_COLUMN_MODE(mw) && (hl & HighlightColumn)) {
168                 DrawColumnHighlight(mw, win, gc, row, column, x, y, width, height);
169         } else if (hl) {
170                 DRAW_HIGHLIGHT(XtDisplay(mw), win,  gc,
171                                x + thick, y + thick, width - 2 * thick, height - 2 * thick,
172                                mw->matrix.cell_highlight_thickness, LineSolid);
173         }
174 }
175 
176 static void
DrawRowHighlight(XbaeMatrixWidget mw,Window win,GC gc,int row,int column,int x,int y,int width,int height)177 DrawRowHighlight(XbaeMatrixWidget mw, Window win, GC gc, int row, int column, int x, int y,
178                  int width, int height)
179 {
180         XRectangle rect;
181 
182         DEBUGOUT(_XbaeDebug
183                  (__FILE__, (Widget) mw, "DrawRowHighlight [%d,%d] wid %d ht %d\n", row, column,
184                   width, height));
185 
186         rect.x = x;
187         rect.y = y;
188         rect.width = width;
189         rect.height = height;
190 
191         XSetClipRectangles(XtDisplay(mw), gc, 0, 0, &rect, 1, Unsorted);
192 
193         /*
194          * The highlight is inside the cell shadow
195          */
196         x += mw->matrix.cell_shadow_thickness;
197         y += mw->matrix.cell_shadow_thickness;
198         width -= 2 * mw->matrix.cell_shadow_thickness;
199         height -= 2 * mw->matrix.cell_shadow_thickness;
200 
201         /*
202          * Make sure the left/right edge are outside the clipping recangle if this
203          * is not the first/last column
204          */
205         if (column != 0) {
206                 x -= mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
207                 width += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
208         }
209         if (column != mw->matrix.columns - 1) {
210                 width += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
211         }
212 
213         DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, width, height,
214                        mw->matrix.cell_highlight_thickness, LineSolid);
215 
216         XSetClipMask(XtDisplay(mw), gc, None);
217 }
218 
219 static void
DrawColumnHighlight(XbaeMatrixWidget mw,Window win,GC gc,int row,int column,int x,int y,int width,int height)220 DrawColumnHighlight(XbaeMatrixWidget mw, Window win, GC gc, int row, int column, int x, int y,
221                  int width, int height)
222 {
223         XRectangle rect;
224 
225         DEBUGOUT(_XbaeDebug
226                  (__FILE__, (Widget) mw, "DrawRowHighlight [%d,%d] wid %d ht %d\n", row, column,
227                   width, height));
228 
229         rect.x = x;
230         rect.y = y;
231         rect.width = width;
232         rect.height = height;
233 
234         XSetClipRectangles(XtDisplay(mw), gc, 0, 0, &rect, 1, Unsorted);
235 
236         /*
237          * The highlight is inside the cell shadow
238          */
239         x += mw->matrix.cell_shadow_thickness;
240         y += mw->matrix.cell_shadow_thickness;
241         width -= 2 * mw->matrix.cell_shadow_thickness;
242         height -= 2 * mw->matrix.cell_shadow_thickness;
243 
244         /*
245          * Make sure the top/bottom edge are outside the clipping recangle if this
246          * is not the first/last row
247          */
248         if (row != 0) {
249                 y -= mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
250                 height += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
251         }
252         if (row != mw->matrix.rows - 1) {
253                 height += mw->matrix.cell_shadow_thickness + mw->matrix.cell_highlight_thickness;
254         }
255 
256         DRAW_HIGHLIGHT(XtDisplay(mw), win, gc, x, y, width, height,
257                        mw->matrix.cell_highlight_thickness, LineSolid);
258 
259         XSetClipMask(XtDisplay(mw), gc, None);
260 }
261 
262 static void
DrawRowShadow(XbaeMatrixWidget mw,Window win,int row,int column,int x,int y,int width,int height,GC topGC,GC bottomGC,unsigned char shadow)263 DrawRowShadow(XbaeMatrixWidget mw, Window win, int row, int column, int x, int y, int width,
264               int height, GC topGC, GC bottomGC, unsigned char shadow)
265 {
266         XRectangle rect;
267 
268         /*
269          * Set up a clipping rectangle over the current cell.
270          */
271         rect.x = x;
272         rect.y = y;
273         rect.width = width;
274         rect.height = height;
275 
276         XSetClipRectangles(XtDisplay(mw), topGC, 0, 0, &rect, 1, Unsorted);
277         if (topGC != bottomGC)
278                 XSetClipRectangles(XtDisplay(mw), bottomGC, 0, 0, &rect, 1, Unsorted);
279 
280         /*
281          * Make sure the left/right edge are outside the clipping recangle if this
282          * is not the first/last column
283          */
284         if (column != 0) {
285                 x -= mw->matrix.cell_shadow_thickness;
286                 width += mw->matrix.cell_shadow_thickness;
287         }
288         if (column != mw->matrix.columns - 1) {
289                 width += mw->matrix.cell_shadow_thickness;
290         }
291 
292         DRAW_SHADOW(XtDisplay(mw), win, "win", topGC, bottomGC,
293                     mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
294 
295         XSetClipMask(XtDisplay(mw), topGC, None);
296         if (topGC != bottomGC)
297                 XSetClipMask(XtDisplay(mw), bottomGC, None);
298 }
299 
300 static void
DrawColumnShadow(XbaeMatrixWidget mw,Window win,int row,int column,int x,int y,int width,int height,GC topGC,GC bottomGC,unsigned char shadow)301 DrawColumnShadow(XbaeMatrixWidget mw, Window win, int row, int column, int x, int y, int width,
302                  int height, GC topGC, GC bottomGC, unsigned char shadow)
303 {
304         XRectangle rect;
305 
306         /*
307          * Set up a clipping rectangle over the current cell.
308          */
309         rect.x = x;
310         rect.y = y;
311         rect.width = width;
312         rect.height = height;
313 
314         XSetClipRectangles(XtDisplay(mw), topGC, 0, 0, &rect, 1, Unsorted);
315         if (topGC != bottomGC)
316                 XSetClipRectangles(XtDisplay(mw), bottomGC, 0, 0, &rect, 1, Unsorted);
317 
318         /*
319          * Make sure the top/bottom edge are outside the clipping recangle if this
320          * is not the first/last row
321          */
322         if (row != 0) {
323                 y -= mw->matrix.cell_shadow_thickness;
324                 height += mw->matrix.cell_shadow_thickness;
325         }
326         if (row != mw->matrix.rows - 1) {
327                 height += mw->matrix.cell_shadow_thickness;
328         }
329 
330         DRAW_SHADOW(XtDisplay(mw), win, "win", topGC, bottomGC,
331                     mw->matrix.cell_shadow_thickness, x, y, width, height, shadow);
332 
333         XSetClipMask(XtDisplay(mw), topGC, None);
334         if (topGC != bottomGC)
335                 XSetClipMask(XtDisplay(mw), bottomGC, None);
336 }
337