1 /*
2 **
3 ** Button.c
4 **
5 ** Copyright (C) 1995, 1996, 1997 Johannes Plass
6 ** Copyright (C) 2004 Jose E. Marchesi
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 3 of the License, or
11 ** (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with GNU gv; see the file COPYING.  If not, write to
20 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ** Boston, MA 02111-1307, USA.
22 **
23 ** Authors:   Johannes Plass (plass@thep.physik.uni-mainz.de)
24 **            Department of Physics
25 **            Johannes Gutenberg-University
26 **            Mainz, Germany
27 **
28 **            Jose E. Marchesi (jemarch@gnu.org)
29 **            GNU Project
30 */
31 #include "ac_config.h"
32 
33 #include <stdio.h>
34 /*
35 #define MESSAGES
36 */
37 #include "message.h"
38 
39 #include "paths.h"
40 #include INC_X11(IntrinsicP.h)
41 #include INC_X11(StringDefs.h)
42 #include INC_XMU(Misc.h)
43 #include INC_XAW(XawInit.h)
44 #include "ButtonP.h"
45 #include INC_XMU(Converters.h)
46 #include INC_XMU(CharSet.h)
47 
48 static void ClassInitialize(void);
49 static void Initialize(Widget,Widget,ArgList,Cardinal*);
50 static void Redisplay(Widget,XEvent *,Region);
51 static void Destroy(Widget);
52 static void PaintButtonWidget(Widget,XEvent *,Region);
53 static void GetSetBackgroundGC(ButtonWidget);
54 static void GetHighlightedBackgroundGC(ButtonWidget);
55 
56 /****************************************************************
57  *
58  * Full class record constant
59  *
60  ****************************************************************/
61 
62 /* Private Data */
63 
64 static char defaultTranslations[] =
65 "<EnterWindow>:highlight()\n\
66 <LeaveWindow>:reset()\n\
67 <Btn1Down>:set()\n\
68 <Btn1Up>:notify()unset()";
69 
70 #define offset(field) XtOffsetOf(ButtonRec, field)
71 static XtResource resources[] = {
72   {XtNsetFrameStyle, XtCSetFrameStyle, XtRFrameType, sizeof(XawFrameType),
73         offset(button.set_frame_style), XtRImmediate, (XtPointer) XawSUNKEN },
74   {XtNunsetFrameStyle, XtCUnsetFrameStyle, XtRFrameType, sizeof(XawFrameType),
75         offset(button.unset_frame_style), XtRImmediate, (XtPointer) XawRAISED },
76   {XtNhighlightedFrameStyle, XtCHighlightedFrameStyle, XtRFrameType, sizeof(XawFrameType),
77         offset(button.highlighted_frame_style), XtRImmediate, (XtPointer) XawRAISED },
78   {XtNsetBackground, XtCSetBackground, XtRPixel, sizeof(Pixel),
79 	offset(button.set_background), XtRString, XtDefaultBackground},
80   {XtNhighlightedBackground, XtCHighlightedBackground, XtRPixel, sizeof(Pixel),
81 	offset(button.highlighted_background), XtRString, XtDefaultBackground},
82   {XtNhighlightThickness, XtCThickness, XtRDimension, sizeof(Dimension),
83         offset(command.highlight_thickness), XtRImmediate,(XtPointer)0},
84   {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
85         XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
86         (XtPointer)0}
87 };
88 #undef offset
89 
90 static XtActionsRec actionsList[] = {
91   {"highlight",	ButtonHighlight},
92   {"set",	ButtonSet},
93   {"reset",	ButtonReset},
94   {"unset",	ButtonUnset},
95 };
96 
97 #define SuperClass ((CommandWidgetClass)&commandClassRec)
98 
99 ButtonClassRec buttonClassRec = {
100   {
101     (WidgetClass) SuperClass,		/* superclass		  */
102     "Button",				/* class_name		  */
103     sizeof(ButtonRec),			/* size			  */
104     ClassInitialize,			/* class_initialize	  */
105     NULL,				/* class_part_initialize  */
106     FALSE,				/* class_inited		  */
107     Initialize,				/* initialize		  */
108     NULL,				/* initialize_hook	  */
109     XtInheritRealize,			/* realize		  */
110     actionsList,			/* actions		  */
111     XtNumber(actionsList),		/* num_actions		  */
112     resources,				/* resources		  */
113     XtNumber(resources),		/* resource_count	  */
114     NULLQUARK,				/* xrm_class		  */
115     TRUE,				/* compress_motion	  */
116     TRUE,				/* compress_exposure	  */
117     TRUE,				/* compress_enterleave    */
118     FALSE,				/* visible_interest	  */
119     Destroy,				/* destroy		  */
120     XtInheritResize,			/* resize		  */
121     Redisplay,				/* expose		  */
122     NULL,				/* set_values		  */
123     NULL,				/* set_values_hook	  */
124     XtInheritSetValuesAlmost,		/* set_values_almost	  */
125     NULL,				/* get_values_hook	  */
126     NULL,				/* accept_focus		  */
127     XtVersion,				/* version		  */
128     NULL,				/* callback_private	  */
129     defaultTranslations,		/* tm_table		  */
130     XtInheritQueryGeometry,		/* query_geometry	  */
131     XtInheritDisplayAccelerator,	/* display_accelerator	  */
132     NULL				/* extension		  */
133   },  /* CoreClass fields initialization */
134   {
135     XtInheritChangeSensitive		/* change_sensitive	*/
136   },  /* SimpleClass fields initialization */
137   {
138     XtInheritXaw3dShadowDraw,           /* shadowdraw           */
139   },  /* ThreeD Class fields initialization */
140   {
141     0,                                     /* field not used    */
142   },  /* LabelClass fields initialization */
143   {
144     0,                                     /* field not used    */
145   },  /* CommandClass fields initialization */
146   {
147     0,                                     /* field not used    */
148   },  /* ButtonClass fields initialization */
149 };
150 
151   /* for public consumption */
152 WidgetClass buttonWidgetClass = (WidgetClass) &buttonClassRec;
153 
154 /*---------------------------------------------------*/
155 /* ClassInitialize */
156 /*---------------------------------------------------*/
157 
ClassInitialize()158 static void ClassInitialize()
159 {
160   BEGINMESSAGE(ClassInitialize)
161   XawInitializeWidgetSet();
162   XtSetTypeConverter(XtRString, XtRFrameType, FrameConvertStringToFrameType,
163 		     (XtConvertArgList)NULL, 0, XtCacheNone, NULL);
164   ENDMESSAGE(ClassInitialize)
165 }
166 
167 /*---------------------------------------------------*/
168 /* Initialize */
169 /*---------------------------------------------------*/
170 
171 static void
Initialize(Widget request _GL_UNUSED,Widget new,ArgList args _GL_UNUSED,Cardinal * num_args _GL_UNUSED)172 Initialize(Widget request _GL_UNUSED, Widget new, ArgList args _GL_UNUSED, Cardinal *num_args _GL_UNUSED)
173 {
174   ButtonWidget bw = (ButtonWidget) new;
175 
176   BEGINMESSAGE(Initialize)
177   GetSetBackgroundGC(bw);
178   GetHighlightedBackgroundGC(bw);
179   bw->button.highlighted = 0;
180   ENDMESSAGE(Initialize)
181 }
182 
183 /*---------------------------------------------------*/
184 /* Redisplay */
185 /*---------------------------------------------------*/
186 
187 static void
Redisplay(w,event,region)188 Redisplay(w, event, region)
189 Widget w;
190 XEvent *event;
191 Region region;
192 {
193   BEGINMESSAGE(Redisplay)
194   PaintButtonWidget(w, event, region);
195   ENDMESSAGE(Redisplay)
196 }
197 
198 /*---------------------------------------------------*/
199 /* Destroy */
200 /*---------------------------------------------------*/
201 
202 static void
Destroy(w)203 Destroy(w)
204 Widget w;
205 {
206   ButtonWidget bw = (ButtonWidget)w;
207 
208   BEGINMESSAGE(Destroy)
209   XtReleaseGC(w,bw->button.set_background_GC);
210   XtReleaseGC(w,bw->button.highlighted_background_GC);
211   ENDMESSAGE(Destroy)
212 }
213 
214 /*---------------------------------------------------*/
215 /* GetHighlightedBackgroundGC */
216 /*---------------------------------------------------*/
217 
GetHighlightedBackgroundGC(bw)218 static void GetHighlightedBackgroundGC(bw)
219   ButtonWidget bw;
220 {
221   XGCValues	values;
222 
223   BEGINMESSAGE(GetHighlightedBackgroundGC)
224   values.foreground	= bw->button.highlighted_background;
225   values.background	= bw->label.foreground;
226   bw->button.highlighted_background_GC = XtGetGC((Widget)bw,(unsigned) (GCForeground | GCBackground),&values);
227   ENDMESSAGE(GetHighlightedBackgroundGC)
228 }
229 
230 /*---------------------------------------------------*/
231 /* GetSetBackgroundGC */
232 /*---------------------------------------------------*/
233 
GetSetBackgroundGC(bw)234 static void GetSetBackgroundGC(bw)
235   ButtonWidget bw;
236 {
237   XGCValues	values;
238 
239   BEGINMESSAGE(GetSetBackgroundGC)
240   values.foreground	= bw->button.set_background;
241   values.background	= bw->label.foreground;
242   bw->button.set_background_GC = XtGetGC((Widget)bw,(unsigned) (GCForeground | GCBackground),&values);
243   ENDMESSAGE(GetSetBackgroundGC)
244 }
245 
246 /*---------------------------------------------------*/
247 /* PaintButtonWidget */
248 /*---------------------------------------------------*/
249 
250 static void
PaintButtonWidget(w,event,region)251 PaintButtonWidget(w, event, region)
252 Widget w;
253 XEvent *event;
254 Region region;
255 {
256   ButtonWidget bw = (ButtonWidget)w;
257   int wh,ww,sw,fs;
258   GC cgc,lgc,gc;
259   Boolean set;
260 
261   BEGINMESSAGE(PaintButtonWidget)
262 
263   if (bw->command.set) {
264     gc = bw->button.set_background_GC;
265   } else if (bw->button.highlighted) {
266     gc = bw->button.highlighted_background_GC;
267   } else {
268     gc = bw->command.inverse_GC;
269   }
270   XFillRectangle(XtDisplay(w), XtWindow(w),gc,0,0,bw->core.width,bw->core.height);
271   region = NULL;
272   lgc = bw->label.normal_GC;
273   sw = (int) bw->threeD.shadow_width;
274   set = bw->command.set;
275   bw->command.set = False;
276 #if 0
277   bw->threeD.shadow_width = 0;
278 #endif
279   cgc = bw->command.normal_GC;
280   if (bw->label.pixmap != None) {
281     bw->command.normal_GC = gc;
282   }
283   (*SuperClass->core_class.expose) (w, event, region);
284   bw->command.set = set;
285   bw->threeD.shadow_width = (Dimension) sw;
286   bw->label.normal_GC = lgc;
287   bw->command.normal_GC = cgc;
288 
289   ww = (int)bw->core.width;
290   wh = (int)bw->core.height;
291   sw = (int)bw->threeD.shadow_width;
292   if      (bw->command.set)        fs = (int)bw->button.set_frame_style;
293   else if (bw->button.highlighted) fs = (int)bw->button.highlighted_frame_style;
294   else                             fs = (int)bw->button.unset_frame_style;
295   if (sw == 0 || 2*sw>ww || 2*sw>wh) {
296     INFMESSAGE(not enough space to display anything) ENDMESSAGE(Redisplay)
297     return;
298   }
299   FrameDrawFrame(w,0,0,ww,wh,fs,sw,bw->threeD.top_shadow_GC,bw->threeD.bot_shadow_GC);
300   ENDMESSAGE(PaintButtonWidget)
301 }
302 
303 /*####################################################################*/
304 /*####################################################################*/
305 /* Public Routines */
306 /*####################################################################*/
307 /*####################################################################*/
308 
309 
310 /*##################################################-*/
311 /* ACTIONS */
312 /*##################################################-*/
313 
314 void
ButtonHighlight(Widget w,XEvent * event,String * params _GL_UNUSED,Cardinal * num_params _GL_UNUSED)315 ButtonHighlight(Widget w, XEvent *event, String *params _GL_UNUSED, Cardinal *num_params _GL_UNUSED)
316 {
317   ButtonWidget bw = (ButtonWidget)w;
318   Boolean set;
319 
320   BEGINMESSAGE(ButtonHighlight)
321   bw->button.highlighted=1;
322   set = bw->command.set;
323   bw->command.set=False;
324   if (XtIsRealized(w)) PaintButtonWidget(w, event, (Region)NULL);
325   bw->command.set=set;
326   ENDMESSAGE(ButtonHighlight)
327 }
328 
329 void
ButtonSet(Widget w,XEvent * event,String * params _GL_UNUSED,Cardinal * num_params _GL_UNUSED)330 ButtonSet(Widget w, XEvent *event, String *params _GL_UNUSED, Cardinal *num_params _GL_UNUSED)
331 {
332   ButtonWidget bw = (ButtonWidget)w;
333 
334   BEGINMESSAGE(ButtonSet)
335   if (!bw->command.set) {
336     bw->command.set= TRUE;
337     if (XtIsRealized(w)) PaintButtonWidget(w, event, (Region)NULL);
338   }
339   ENDMESSAGE(ButtonSet)
340 }
341 
342 void
ButtonUnset(Widget w,XEvent * event,String * params _GL_UNUSED,Cardinal * num_params _GL_UNUSED)343 ButtonUnset(Widget w, XEvent *event, String *params _GL_UNUSED, Cardinal *num_params _GL_UNUSED)
344 {
345   ButtonWidget bw = (ButtonWidget)w;
346 
347   BEGINMESSAGE(ButtonUnset)
348   bw->command.set = FALSE;
349   if (XtIsRealized(w)) PaintButtonWidget(w, event, (Region)NULL);
350   ENDMESSAGE(ButtonUnset)
351 }
352 
353 void
ButtonReset(w,event,params,num_params)354 ButtonReset(w,event,params,num_params)
355 Widget w;
356 XEvent *event;
357 String *params;		/* unused */
358 Cardinal *num_params;   /* unused */
359 {
360   ButtonWidget bw = (ButtonWidget)w;
361 
362   BEGINMESSAGE(ButtonReset)
363   bw->button.highlighted = 0;
364   ButtonUnset(w, event, params, num_params);
365   ENDMESSAGE(ButtonReset)
366 }
367 
368