1 /*
2  * $Id: LabelH.c,v 1.1 1998/01/07 03:49:23 cwikla Exp $
3  * Copyright 1998 John L. Cwikla
4  *
5  * Permission to use, copy, modify, distribute, and sell this software
6  * and its documentation for any purpose is hereby granted without fee,
7  * provided that the above copyright notice appears in all copies and that
8  * both that copyright notice and this permission notice appear in
9  * supporting documentation, and that the name of John L. Cwikla or
10  * Wolfram Research, Inc not be used in advertising or publicity
11  * pertaining to distribution of the software without specific, written
12  * prior permission.  John L. Cwikla and Wolfram Research, Inc make no
13  * representations about the suitability of this software for any
14  * purpose.  It is provided "as is" without express or implied warranty.
15  *
16  * John L. Cwikla and Wolfram Research, Inc disclaim all warranties with
17  * regard to this software, including all implied warranties of
18  * merchantability and fitness, in no event shall John L. Cwikla or
19  * Wolfram Research, Inc be liable for any special, indirect or
20  * consequential damages or any damages whatsoever resulting from loss of
21  * use, data or profits, whether in an action of contract, negligence or
22  * other tortious action, arising out of or in connection with the use or
23  * performance of this software.
24  *
25  * Author:
26  *  John L. Cwikla
27  *  X Programmer
28  *  Wolfram Research Inc.
29  *
30  *  cwikla@wolfram.com
31  */
32 #ifndef lint
33 static char *_LabelH_c_ident_ = "@(#)LabelH.c	7.8 03/12/12";
34 #endif
35 
36 #include <Xm/Xm.h>
37 
38 #if !defined(LesstifVersion) && !defined(NO_LABELH) && XmVersion > 1001
39 /* Labelhack doesn't work with recent versions of Lesstif */
40 
41 #include <Xm/XmP.h>
42 #include <Xm/LabelP.h>
43 #include <Xm/LabelGP.h>
44 #include <Xm/ManagerP.h>
45 
46 #include "LabelHP.h"
47 
48 static void	initialize(XmLabelHackWidget _request, XmLabelHackWidget _new,
49 			   String *_args, Cardinal *_numArg);
50 static void	_replaceLabelExpose(void);
51 static void	_replaceLabelGadgetExpose(void);
52 static GC	_topShadowGC(XmLabelWidget _label);
53 static GC	_bottomShadowGC(XmLabelWidget _label);
54 
55 
56 #define CORE(w)			((w)->core)
57 #define PRIM(w)			((w)->primitive)
58 #define MANAGER(w)		((w)->manager)
59 #define LABEL(w)		((w)->label)
60 #define HACK(w)			((w)->label_hack)
61 #define HACK_CLASS(w)		((w)->label_hack_class)
62 
63 #define TheOffset(field)	XtOffset(XmLabelHackWidget, label_hack.field)
64 #define PrimOffset(field)	XtOffset(XmLabelHackWidget, primitive.field)
65 
66 
67 static XtResource resources[] = {
68 	{ XmNinsensitive3D, XmCInsensitive3D, XmRBoolean, sizeof(Boolean),
69 	  TheOffset(insensitive3D), XmRImmediate, (XtPointer)TRUE },
70 };
71 
72 
73 XmLabelHackClassRec xmLabelHackClassRec = {
74 	{
75 		(WidgetClass)&xmLabelClassRec,		/* superclass */
76 		"XmLabelHack",				/* class_name */
77 		(Cardinal)sizeof(XmLabelHackRec),	/* widget size */
78 		(XtProc)NULL,				/* class_init */
79 		(XtWidgetClassProc)NULL,		/* class_part_init */
80 		(XtEnum)FALSE,				/* class_inited */
81 		(XtInitProc)initialize,			/* initialize */
82 		(XtArgsProc)NULL,			/* init_hook */
83 		XtInheritRealize,			/* realize */
84 		(XtActionList)NULL,			/* actions */
85 		(Cardinal)0,				/* num_actions */
86 		(XtResourceList)resources,		/* resources */
87 		(Cardinal)XtNumber(resources),		/* num_resources */
88 		NULLQUARK,				/* xrm_class */
89 		TRUE,					/* compr_motion */
90 		(XtEnum)TRUE,				/* compr_exposur */
91 		TRUE,					/* compr_enterleav */
92 		FALSE,					/* visib_interest */
93 		(XtWidgetProc)NULL,			/* destroy */
94 		(XtWidgetProc)XtInheritResize,
95 		(XtExposeProc)NULL,
96 		(XtSetValuesFunc)NULL,			/* set_values */
97 		(XtArgsFunc)NULL,			/* set_values_hook */
98 		XtInheritSetValuesAlmost,		/* set_values_almost */
99 		(XtArgsProc)NULL,			/* get_values_hook */
100 		NULL,					/* accept_focus */
101 		XtVersion,				/* version */
102 		(XtPointer)NULL,			/* callback_private */
103 		XtInheritTranslations,			/* tm_table */
104 		(XtGeometryHandler)NULL, 		/* query_geometry */
105 		NULL, 					/* displ_accelerator */
106 		(XtPointer)NULL,			/* extension */
107 	},
108 	{ 	/* xmPrimitiveClass */
109 		(XtWidgetProc)XmInheritBorderHighlight,
110 		(XtWidgetProc)XmInheritBorderUnhighlight,
111 		XtInheritTranslations,
112 		(XtActionProc)XmInheritArmAndActivate,
113 		NULL,
114 		0,
115 		(XtPointer)NULL,
116 	},
117 	{	/* xmLabelClass */
118 		(XtWidgetProc) XmInheritSetOverrideCallback,
119 		XmInheritMenuProc,
120 		XtInheritTranslations,
121 		NULL,
122 	},
123 	{
124 		-1,
125 	}
126 };
127 
128 
129 WidgetClass xmLabelHackWidgetClass = (WidgetClass)&xmLabelHackClassRec;
130 
131 /*ARGSUSED*/
132 static void
initialize(XmLabelHackWidget _request,XmLabelHackWidget _new,String * _args,Cardinal * _numArgs)133 initialize(
134 	XmLabelHackWidget	_request,
135 	XmLabelHackWidget	_new,
136 	String			*_args,
137 	Cardinal		*_numArgs
138 )
139 {
140 	XmLabelHackWidgetClass	lhwc;
141 
142 	lhwc = (XmLabelHackWidgetClass)xmLabelHackWidgetClass;
143 
144 	XtInitializeWidgetClass(xmLabelGadgetClass);
145 
146 	if (HACK_CLASS(lhwc).on == -1) {
147 		if (HACK(_new).insensitive3D && CORE(_new).depth > 4) {
148 			_replaceLabelExpose();
149 			_replaceLabelGadgetExpose();
150 
151 			/* keep around so there is one in the cache */
152 			HACK(_new).topGC = _topShadowGC((XmLabelWidget)_new);
153 			HACK(_new).bottomGC =
154 				_bottomShadowGC((XmLabelWidget)_new);
155 		}
156 
157 		HACK_CLASS(lhwc).on = HACK(_new).insensitive3D;
158 
159 	}
160 
161 	if ((CORE(_new).width == 0) || (CORE(_new).height == 0)) {
162 		CORE(_new).width = 1;
163 		CORE(_new).height = 1;
164 	}
165 }
166 
167 static XtExposeProc oldLabelExposeProc;
168 
169 
170 static GC
_topShadowGC(XmLabelWidget _label)171 _topShadowGC(XmLabelWidget _label)
172 {
173 	XGCValues	gcValues;
174 	XtGCMask	mask;
175 	XFontStruct	*fs;
176 
177 	mask = GCForeground | GCBackground;
178 	gcValues.foreground = PRIM(_label).top_shadow_color;
179 	gcValues.background = PRIM(_label).foreground;
180 
181 	if ((PRIM(_label).top_shadow_pixmap != None) &&
182 	    (PRIM(_label).top_shadow_pixmap != XmUNSPECIFIED_PIXMAP)) {
183 		mask |= GCFillStyle | GCTile;
184 		gcValues.fill_style = FillTiled;
185 		gcValues.tile = PRIM(_label).top_shadow_pixmap;
186 	}
187 
188 	_XmFontListGetDefaultFont(LABEL(_label).font, &fs);
189 	if (fs != NULL) {
190 		mask |= GCFont;
191 		gcValues.font = fs->fid;
192 	}
193 
194 	return XtGetGC((Widget)_label,  mask, &gcValues);
195 }
196 
197 
198 static GC
_bottomShadowGC(XmLabelWidget _label)199 _bottomShadowGC(XmLabelWidget _label)
200 {
201 	XGCValues	gcValues;
202 	XtGCMask	mask;
203 	XFontStruct	*fs;
204 
205 	mask = GCForeground | GCBackground;
206 	gcValues.foreground = PRIM(_label).bottom_shadow_color;
207 	gcValues.background = PRIM(_label).foreground;
208 
209 	if ((PRIM(_label).bottom_shadow_pixmap != None) &&
210 	    (PRIM(_label).bottom_shadow_pixmap != XmUNSPECIFIED_PIXMAP)) {
211 		mask |= GCFillStyle | GCTile;
212 		gcValues.fill_style = FillTiled;
213 		gcValues.tile = PRIM(_label).bottom_shadow_pixmap;
214 	}
215 
216 	_XmFontListGetDefaultFont(LABEL(_label).font, &fs);
217 	if (fs != NULL) {
218 		mask |= GCFont;
219 		gcValues.font = fs->fid;
220 	}
221 
222 	return XtGetGC((Widget)_label,  mask, &gcValues);
223 }
224 
225 
226 static void
_grabbedLabelExpose(Widget _w,XEvent * _event,Region _region)227 _grabbedLabelExpose(Widget _w, XEvent *_event, Region _region)
228 {
229 	GC	insensitiveGC;
230 
231 	XmLabelWidget label = (XmLabelWidget)_w;
232 
233 	if (XtIsSensitive(_w))
234 		(*oldLabelExposeProc)(_w, _event, _region);
235 	else {
236 		insensitiveGC = LABEL(label).insensitive_GC;
237 
238 		LABEL(label).TextRect.x += 1;
239 		LABEL(label).TextRect.y += 1;
240 		if (LABEL(label)._acc_text != NULL) {
241 			LABEL(label).acc_TextRect.x += 1;
242 			LABEL(label).acc_TextRect.y += 1;
243 		}
244 		LABEL(label).insensitive_GC = _topShadowGC(label);
245 		(*oldLabelExposeProc)(_w, _event, _region);
246 		XtReleaseGC(_w, LABEL(label).insensitive_GC);
247 
248 		LABEL(label).TextRect.x -= 1;
249 		LABEL(label).TextRect.y -= 1;
250 		if (LABEL(label)._acc_text != NULL) {
251 			LABEL(label).acc_TextRect.x -= 1;
252 			LABEL(label).acc_TextRect.y -= 1;
253 		}
254 		LABEL(label).insensitive_GC = _bottomShadowGC(label);
255 		(*oldLabelExposeProc)(_w, _event, _region);
256 		XtReleaseGC(_w, LABEL(label).insensitive_GC);
257 
258 		LABEL(label).insensitive_GC = insensitiveGC;
259 	}
260 }
261 
262 
263 static void
_replaceLabelExpose(void)264 _replaceLabelExpose(void)
265 {
266 	oldLabelExposeProc = xmLabelWidgetClass->core_class.expose;
267 	xmLabelWidgetClass->core_class.expose = _grabbedLabelExpose;
268 }
269 
270 
271 static XtExposeProc oldLabelGadgetExposeProc;
272 
273 static GC
_gadgetParentTopShadowGC(XmLabelGadget _label)274 _gadgetParentTopShadowGC(XmLabelGadget _label)
275 {
276 	XGCValues	gcValues;
277 	XtGCMask	mask;
278 	XFontStruct	*fs;
279 	XmManagerWidget	parent = (XmManagerWidget)XtParent(_label);
280 
281 	mask = GCForeground | GCBackground;
282 	gcValues.foreground = MANAGER(parent).top_shadow_color;
283 	gcValues.background = MANAGER(parent).foreground;
284 
285 	if ((MANAGER(parent).top_shadow_pixmap != None) &&
286 	    (MANAGER(parent).top_shadow_pixmap != XmUNSPECIFIED_PIXMAP)) {
287 		mask |= GCFillStyle | GCTile;
288 		gcValues.fill_style = FillTiled;
289 		gcValues.tile = MANAGER(parent).top_shadow_pixmap;
290 	}
291 
292 	_XmFontListGetDefaultFont(LABEL(_label).font, &fs);
293 	if (fs != NULL) {
294 		mask |= GCFont;
295 		gcValues.font = fs->fid;
296 	}
297 
298 	return XtGetGC((Widget)parent,  mask, &gcValues);
299 }
300 
301 
302 static GC
_gadgetParentBottomShadowGC(XmLabelGadget _label)303 _gadgetParentBottomShadowGC(XmLabelGadget _label)
304 {
305 	XGCValues	gcValues;
306 	XtGCMask	mask;
307 	XFontStruct	*fs;
308 	XmManagerWidget	parent = (XmManagerWidget)XtParent(_label);
309 
310 	mask = GCForeground | GCBackground;
311 	gcValues.foreground = MANAGER(parent).bottom_shadow_color;
312 	gcValues.background = MANAGER(parent).foreground;
313 
314 	if ((MANAGER(parent).bottom_shadow_pixmap != None) &&
315 	    (MANAGER(parent).bottom_shadow_pixmap != XmUNSPECIFIED_PIXMAP)) {
316 		mask |= GCFillStyle | GCTile;
317 		gcValues.fill_style = FillTiled;
318 		gcValues.tile = MANAGER(parent).bottom_shadow_pixmap;
319 	}
320 
321 	_XmFontListGetDefaultFont(LABEL(_label).font, &fs);
322 	if (fs != NULL) {
323 		mask |= GCFont;
324 		gcValues.font = fs->fid;
325 	}
326 
327 	return XtGetGC((Widget)parent,  mask, &gcValues);
328 }
329 
330 
331 static void
_grabbedLabelGadgetExpose(Widget _w,XEvent * _event,Region _region)332 _grabbedLabelGadgetExpose(Widget _w, XEvent *_event, Region _region)
333 {
334 	GC	insensitiveGC;
335 
336 	XmLabelGadget label = (XmLabelGadget)_w;
337 
338 	if (XtIsSensitive(_w))
339 		(*oldLabelGadgetExposeProc)(_w, _event, _region);
340 	else {
341 		insensitiveGC = LABEL(label).insensitive_GC;
342 
343 		LABEL(label).TextRect.x += 1;
344 		LABEL(label).TextRect.y += 1;
345 		if (LABEL(label)._acc_text != NULL) {
346 			LABEL(label).acc_TextRect.x += 1;
347 			LABEL(label).acc_TextRect.y += 1;
348 		}
349 		LABEL(label).insensitive_GC = _gadgetParentTopShadowGC(label);
350 		(*oldLabelGadgetExposeProc)(_w, _event, _region);
351 		XtReleaseGC(_w, LABEL(label).insensitive_GC);
352 
353 		LABEL(label).TextRect.x -= 1;
354 		LABEL(label).TextRect.y -= 1;
355 		if (LABEL(label)._acc_text != NULL)
356 		{
357 			LABEL(label).acc_TextRect.x -= 1;
358 			LABEL(label).acc_TextRect.y -= 1;
359 		}
360 		LABEL(label).insensitive_GC =
361 			_gadgetParentBottomShadowGC(label);
362 		(*oldLabelGadgetExposeProc)(_w, _event, _region);
363 		XtReleaseGC(_w, LABEL(label).insensitive_GC);
364 
365 		LABEL(label).insensitive_GC = insensitiveGC;
366 	}
367 }
368 
369 
370 static void
_replaceLabelGadgetExpose(void)371 _replaceLabelGadgetExpose(void)
372 {
373 	oldLabelGadgetExposeProc = xmLabelGadgetClass->core_class.expose;
374 	xmLabelGadgetClass->core_class.expose = _grabbedLabelGadgetExpose;
375 }
376 
377 #else
378 
379 void
nullfunc(void)380 nullfunc(void)
381 {
382 }
383 
384 #endif	/* LesstifVersion NO_LABELH XmVersion */
385 
386