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