Commit | Line | Data |
---|---|---|
2f96293d RS |
1 | |
2 | #include "../src/lisp.h" | |
3 | ||
40a6a4dd RS |
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 | { | |
908ff139 | 231 | /* in OLIT this would have to be a structural change on the |
40a6a4dd RS |
232 | button. */ |
233 | abort (); | |
234 | } | |
235 | } | |
236 | else if (!contents) | |
237 | { | |
908ff139 | 238 | /* in OLIT this would have to be a structural change on the button. */ |
40a6a4dd RS |
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 |