1 /*
2  *  Copyright (C) 1995, 1996  Karl-Johan Johnsson.
3  */
4 
5 #include <X11/IntrinsicP.h>
6 #include <X11/StringDefs.h>
7 
8 #include "Compat.h"
9 #include "Util.h"
10 #include "StringGP.h"
11 
12 static XtResource resources[] = {
13 #define offset(field) XtOffsetOf(StringGadgetRec, string_g.field)
14     {XtNcommand, XtCCommand, XtRString, sizeof(String),
15      offset(command), XtRImmediate, (XtPointer)NULL},
16     {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
17      offset(font), XtRString, XtDefaultFont},
18     {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
19      offset(foreground_pixel), XtRString, XtDefaultForeground},
20     {XtNleftMargin, XtCMargin, XtRDimension, sizeof(Dimension),
21      offset(left_margin), XtRImmediate, (XtPointer)24},
22     {XtNrightMargin, XtCMargin, XtRDimension, sizeof(Dimension),
23      offset(right_margin), XtRImmediate, (XtPointer)32},
24     {XtNinternalHeight, XtCInternalHeight, XtRDimension, sizeof(Dimension),
25      offset(internal_height), XtRImmediate, (XtPointer)2},
26     {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
27      offset(shadow_width), XtRImmediate, (XtPointer)2},
28 #undef offset
29 };
30 
31 static void	Initialize(Widget, Widget, ArgList, Cardinal*);
32 static void	Destroy(Widget);
33 static Boolean	SetValues(Widget, Widget, Widget, ArgList, Cardinal*);
34 static void	Redisplay(Widget, XEvent*, Region);
35 
36 StringGadgetClassRec stringGadgetClassRec = {
37     { /* rectObj fields */
38         (WidgetClass) &menuGadgetClassRec, /* superclass                */
39         "StringGadget",                 /* class_name                   */
40         sizeof(StringGadgetRec),        /* widget_size                  */
41         NULL,                           /* class_initialize             */
42         NULL,                           /* class_part_initialize        */
43         FALSE,                          /* class_inited                 */
44         Initialize,                     /* initialize                   */
45         NULL,                           /* initialize_hook              */
46         NULL,                           /* rect1                        */
47         NULL,                           /* rect2                        */
48         0,                              /* rect3                        */
49         resources,                      /* resources                    */
50         XtNumber(resources),            /* num_resources                */
51         NULLQUARK,                      /* xrm_class                    */
52         FALSE,                          /* rect4                        */
53         FALSE,                          /* rect5                        */
54         FALSE,                          /* rect6                        */
55         FALSE,                          /* rect7                        */
56         Destroy,    			/* destroy                      */
57         NULL,                           /* resize                       */
58         Redisplay,                      /* expose                       */
59         SetValues,                      /* set_values                   */
60         NULL,                           /* set_values_hook              */
61         XtInheritSetValuesAlmost,       /* set_values_almost            */
62         NULL,                           /* get_values_hook              */
63         NULL,                           /* rect9                        */
64         XtVersion,                      /* version                      */
65         NULL,                           /* callback_private             */
66         NULL,                           /* rect10                       */
67         NULL,                           /* query_geometry               */
68         NULL,                           /* rect11                       */
69         NULL,                           /* extension                    */
70     },
71     { /* menu_g fields */
72         XtInheritChangeHl,		/* change_hl			*/
73 	XtInheritPopdown,		/* popdown			*/
74 	XtInheritNotify,		/* notify			*/
75 	XtInheritPostNotify,		/* post_notify			*/
76 	XtInheritSetActive,		/* set_actvive			*/
77 	False,				/* ignore_leave			*/
78 	NULL,				/* extension			*/
79     },
80     { /* string_g fields */
81 	NULL,				/* extension			*/
82     },
83 };
84 
85 WidgetClass stringGadgetClass = (WidgetClass)&stringGadgetClassRec;
86 
87 /*************************************************************************/
88 
set_preferred_size(StringGadget g)89 static void set_preferred_size(StringGadget g)
90 {
91     g->rectangle.width = g->string_g.left_margin +
92 	g->string_g.right_margin + 2 * g->string_g.shadow_width;
93 
94     g->rectangle.width +=
95 	XTextWidth(g->string_g.font, g->menu_g.label, strlen(g->menu_g.label));
96 
97     g->rectangle.height =
98 	2 * (g->string_g.internal_height + g->string_g.shadow_width) +
99 	g->string_g.font->ascent + g->string_g.font->descent;
100 }
101 
init_gcs(StringGadget g)102 static void init_gcs(StringGadget g)
103 {
104     XGCValues	values;
105 
106     values.font = g->string_g.font->fid;
107     values.foreground = g->string_g.foreground_pixel;
108     values.stipple = g->string_g.stipple;
109     values.fill_style =  FillStippled;
110     g->string_g.default_gc =
111 	XtGetGC(g->object.parent, GCForeground | GCFont, &values);
112     g->string_g.gray_gc =
113 	XtGetGC(g->object.parent,
114 		GCForeground | GCFont | GCFillStyle | GCStipple,
115 		&values);
116 }
117 
free_gcs(StringGadget g)118 static void free_gcs(StringGadget g)
119 {
120     XtReleaseGC(g->object.parent, g->string_g.default_gc);
121     XtReleaseGC(g->object.parent, g->string_g.gray_gc);
122 }
123 
124 /*************************************************************************/
125 
Initialize(Widget grequest,Widget gnew,ArgList args,Cardinal * no_args)126 static void Initialize(Widget grequest, Widget gnew,
127 		       ArgList args, Cardinal *no_args)
128 {
129     StringGadget	new = (StringGadget)gnew;
130 
131     set_preferred_size(new);
132     new->string_g.stipple = create_stipple(XtScreen(new->object.parent));
133     init_gcs(new);
134 }
135 
Destroy(Widget gw)136 static void Destroy(Widget gw)
137 {
138     StringGadget	g = (StringGadget)gw;
139 
140     release_stipple(XtScreen(g->object.parent), g->string_g.stipple);
141     free_gcs(g);
142 }
143 
Redisplay(Widget gw,XEvent * event,Region region)144 static void Redisplay(Widget gw, XEvent *event, Region region)
145 {
146     StringGadget	g = (StringGadget)gw;
147     ShadowWidget	parent = (ShadowWidget)g->object.parent;
148     Display		*disp = XtDisplay(parent);
149     Window		win = XtWindow(parent);
150 
151     XDrawString(disp, win,
152 		XtIsSensitive((Widget)g) ?
153 		g->string_g.default_gc : g->string_g.gray_gc,
154 		g->rectangle.x + g->string_g.left_margin +
155 		g->string_g.shadow_width,
156 		g->rectangle.y + (int)(g->rectangle.height +
157 				       g->string_g.font->ascent -
158 				       g->string_g.font->descent) / 2,
159 		g->menu_g.label, strlen(g->menu_g.label));
160 
161     if (g->menu_g.hl) {
162 	int	old_sw = parent->shadow.shadow_width;
163 
164 	parent->shadow.shadow_width = g->string_g.shadow_width;
165 	ShadowDrawShadows(parent, g->rectangle.x, g->rectangle.y,
166 			  g->rectangle.width, g->rectangle.height, False);
167 	parent->shadow.shadow_width = old_sw;
168     }
169 }
170 
SetValues(Widget gcurrent,Widget grequest,Widget gnew,ArgList args,Cardinal * num_args)171 static Boolean SetValues(Widget gcurrent,
172 			 Widget grequest,
173 			 Widget gnew,
174 			 ArgList args,
175 			 Cardinal *num_args)
176 {
177     Boolean		redisplay = False;
178     StringGadget	new = (StringGadget)gnew;
179     StringGadget	current = (StringGadget)gcurrent;
180 
181     if (new->string_g.font             != current->string_g.font ||
182 	new->string_g.foreground_pixel != current->string_g.foreground_pixel) {
183 	free_gcs(current);
184 	init_gcs(new);
185 	redisplay = True;
186     }
187 
188     return redisplay;
189 }
190 
191 /*********************************************************************/
192 
StringGadgetCommand(Widget gw)193 char *StringGadgetCommand(Widget gw)
194 {
195     StringGadget	w = (StringGadget)gw;
196 
197     return w->string_g.command;
198 }
199