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