entered into RCS
[bpt/emacs.git] / lwlib / lwlib-Xol.c
1 #include "lwlib-Xol.h"
2 #include <X11/StringDefs.h>
3 #include <X11/IntrinsicP.h>
4 #include <X11/CompositeP.h>
5 #include <X11/Shell.h>
6 #include <Xol/Menu.h>
7 #include <Xol/OpenLook.h>
8 #include <Xol/MenuButton.h>
9 #include <Xol/OblongButt.h>
10 #include <Xol/ControlAre.h>
11 #include <Xol/Stub.h>
12 #include <Xol/StaticText.h>
13
14 \f/* forward declarations */
15 static void
16 update_menu_widget (widget_instance* instance, Widget widget,
17 widget_value* val);
18
19 \f/* Menu callbacks */
20 static void
21 pre_hook (Widget w, caddr_t client_data, caddr_t call_data)
22 {
23 OlVirtualEvent ve = (OlVirtualEvent)call_data;
24 widget_instance* instance = (widget_instance*)client_data;
25
26 if (w->core.being_destroyed)
27 return;
28
29 if (XtParent (w) == instance->widget)
30 {
31 if (ve->xevent->type == ButtonPress && instance->info->pre_activate_cb)
32 instance->info->pre_activate_cb (instance->widget, instance->info->id,
33 NULL);
34 }
35 }
36
37 static void
38 post_hook (Widget w, caddr_t client_data, caddr_t call_data)
39 {
40 widget_instance* instance = (widget_instance*)client_data;
41
42 if (w->core.being_destroyed)
43 return;
44
45 if (instance->info->post_activate_cb)
46 instance->info->post_activate_cb (w, instance->info->id, NULL);
47 }
48
49 static void
50 pick_hook (Widget w, caddr_t client_data, caddr_t call_data)
51 {
52 widget_instance* instance = 0;
53 widget_value* val = (widget_value*)client_data;
54
55 if (w->core.being_destroyed)
56 return;
57
58 XtVaGetValues (w, XtNuserData, &instance, 0);
59
60 if (!instance)
61 return;
62
63 if (instance->info->selection_cb && val && val->enabled
64 && !val->contents)
65 instance->info->selection_cb (w, instance->info->id, val->call_data);
66 }
67
68 \f/* creation functions */
69 static Widget
70 xol_create_menubar (widget_instance* instance)
71 {
72 Widget widget =
73 XtVaCreateWidget (instance->info->name, controlAreaWidgetClass,
74 instance->parent, 0);
75 return widget;
76 }
77
78 static Widget
79 xol_create_popup_menu (widget_instance* instance)
80 {
81 Widget popup_shell =
82 XtCreatePopupShell (instance->info->name, menuShellWidgetClass,
83 instance->parent, NULL, 0);
84 return popup_shell;
85 }
86
87 widget_creation_entry
88 xol_creation_table [] =
89 {
90 {"menubar", xol_create_menubar},
91 {"popup", xol_create_popup_menu},
92 {NULL, NULL}
93 };
94
95 Widget
96 xol_create_dialog (widget_instance* instance)
97 {
98 return NULL;
99 }
100
101 Boolean
102 lw_olit_widget_p (Widget widget)
103 {
104 return True;
105 }
106
107 \f/* update functions */
108 static void
109 destroy_all_children (Widget widget)
110 {
111 Widget* children;
112 unsigned int number;
113 int i;
114
115 children = (Widget *) XtCompositeChildren (widget, &number);
116 if (children)
117 {
118 /* Unmanage all children and destroy them. They will only be
119 * really destroyed when we get out of DispatchEvent. */
120 for (i = 0; i < number; i++)
121 {
122 Widget child = children [i];
123 if (!child->core.being_destroyed)
124 {
125 XtUnmanageChild (child);
126 XtDestroyWidget (child);
127 }
128 }
129 XtFree (children);
130 }
131 }
132
133 static Boolean
134 all_dashes_p (char* s)
135 {
136 char* t;
137 for (t = s; *t; t++)
138 if (*t != '-')
139 return False;
140 return True;
141 }
142
143 static void
144 make_menu_in_widget (widget_instance* instance, Widget widget,
145 widget_value* val)
146 {
147 widget_value* cur;
148 Widget button;
149 Arg al [256];
150 int ac;
151 String label;
152
153 for (cur = val; cur; cur = cur->next)
154 {
155 ac = 0;
156 XtSetArg (al [ac], XtNsensitive, cur->enabled); ac++;
157 XtSetArg (al [ac], XtNuserData, instance); ac++;
158 XtSetArg (al [ac], XtNacceleratorText, cur->key); ac++;
159
160 /* label = (char *) resource_string (widget, cur->name);*/
161 label = cur->name;
162 if (label)
163 {
164 XtSetArg (al [ac], XtNlabel, label); ac++;
165 }
166
167 if (all_dashes_p (cur->name))
168 {
169 /* no separator in OpenLook just make some space. */
170 XtSetArg (al [ac], XtNheight, 5); ac++;
171 XtSetArg (al [ac], XtNwidth, 5); ac++;
172 button = XtCreateWidget (cur->name, stubWidgetClass, widget, al, ac);
173 }
174 else if (!cur->contents)
175 {
176 if (!cur->call_data)
177 button =
178 XtCreateManagedWidget (cur->name, staticTextWidgetClass, widget,
179 al, ac);
180 else
181 {
182 button =
183 XtCreateManagedWidget (cur->name, oblongButtonWidgetClass,
184 widget, al, ac);
185 XtAddCallback (button, XtNselect, pick_hook, cur);
186 }
187 }
188 else
189 {
190 Widget menu = NULL;
191 button =
192 XtCreateManagedWidget (cur->name, menuButtonWidgetClass, widget,
193 al, ac);
194 XtVaGetValues (button, XtNmenuPane, &menu, 0);
195 if (!menu)
196 abort ();
197 make_menu_in_widget (instance, menu, cur->contents);
198 OlAddCallback (button, XtNconsumeEvent, pre_hook, instance);
199 }
200 }
201 }
202
203 static void
204 update_one_menu_entry (widget_instance* instance, Widget widget,
205 widget_value* val)
206 {
207 Arg al [256];
208 int ac;
209 Widget menu;
210 widget_value* contents;
211
212 if (val->change == NO_CHANGE)
213 return;
214
215 /* update the sensitivity */
216 XtVaSetValues (widget, XtNsensitive, val->enabled, 0);
217
218 /* update the pulldown/pullaside as needed */
219 ac = 0;
220 menu = NULL;
221 XtVaGetValues (widget, XtNmenuPane, &menu, 0);
222 contents = val->contents;
223
224 if (!menu)
225 {
226 if (contents)
227 {
228 /* in OLIT this woudl have to be a structural change on the
229 button. */
230 abort ();
231 }
232 }
233 else if (!contents)
234 {
235 /* in OLIT this woudl have to be a structural change on the button. */
236 abort ();
237 }
238 else if (contents->change != NO_CHANGE)
239 update_menu_widget (instance, menu, val);
240 }
241
242 static void
243 update_menu_widget (widget_instance* instance, Widget widget,
244 widget_value* val)
245
246 {
247 if (val->change == STRUCTURAL_CHANGE
248 || val->contents->change == STRUCTURAL_CHANGE)
249 {
250 destroy_all_children (widget);
251 make_menu_in_widget (instance, widget, val->contents);
252 }
253 else
254 {
255 /* Update all the buttons of the composite widget in order. */
256 Widget* children;
257 unsigned int num_children;
258 int i;
259 widget_value* cur;
260
261 children = (Widget *) XtCompositeChildren (widget, &num_children);
262 if (children)
263 {
264 for (i = 0, cur = val->contents; i < num_children; i++)
265 {
266 if (!cur)
267 abort ();
268 if (children [i]->core.being_destroyed
269 || strcmp (XtName (children [i]), cur->name))
270 continue;
271 update_one_menu_entry (instance, children [i], cur);
272 cur = cur->next;
273 }
274 XtFree (children);
275 }
276 if (cur)
277 abort ();
278 }
279 }
280
281 void
282 xol_update_one_widget (widget_instance* instance, Widget widget,
283 widget_value* val, Boolean deep_p)
284 {
285 Widget menu = widget;
286
287 if (XtIsShell (widget))
288 XtVaGetValues (widget, XtNmenuPane, &menu, 0);
289
290 update_menu_widget (instance, menu, val);
291 }
292
293 void
294 xol_update_one_value (widget_instance* instance, Widget widget,
295 widget_value* val)
296 {
297 return;
298 }
299
300 void
301 xol_pop_instance (widget_instance* instance, Boolean up)
302 {
303 }
304
305 void
306 xol_popup_menu (Widget widget)
307 {
308 OlMenuPost (widget);
309 }
310
311 \f/* Destruction of instances */
312 void
313 xol_destroy_instance (widget_instance* instance)
314 {
315 XtDestroyWidget (instance->widget);
316 }
317