Mercurial > hg > xemacs-beta
comparison lwlib/lwlib-Xlw.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 /* The lwlib interface to "xlwmenu" menus. | |
2 Copyright (C) 1992, 1994 Lucid, Inc. | |
3 | |
4 This file is part of the Lucid Widget Library. | |
5 | |
6 The Lucid Widget Library is free software; you can redistribute it and/or | |
7 modify it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2, or (at your option) | |
9 any later version. | |
10 | |
11 The Lucid Widget Library is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 #include <stdlib.h> /* for abort () */ | |
21 #include <limits.h> | |
22 | |
23 #include "lwlib-Xlw.h" | |
24 #include <X11/StringDefs.h> | |
25 #include <X11/IntrinsicP.h> | |
26 #include <X11/ObjectP.h> | |
27 #include <X11/CompositeP.h> | |
28 #include <X11/Shell.h> | |
29 #ifdef MENUBARS_LUCID | |
30 #include "xlwmenu.h" | |
31 #endif | |
32 #ifdef SCROLLBARS_LUCID | |
33 #include "xlwscrollbar.h" | |
34 #endif | |
35 | |
36 | |
37 | |
38 #ifdef MENUBARS_LUCID | |
39 | |
40 /* Menu callbacks */ | |
41 | |
42 static void | |
43 pre_hook (Widget w, XtPointer client_data, XtPointer call_data) | |
44 { | |
45 widget_instance* instance = (widget_instance*)client_data; | |
46 widget_value* val; | |
47 | |
48 if (w->core.being_destroyed) | |
49 return; | |
50 | |
51 val = lw_get_widget_value_for_widget (instance, w); | |
52 #if 0 | |
53 /* #### - this code used to (for some random back_asswards reason) pass | |
54 the expression below in the call_data slot. For incremental menu | |
55 construction, this needs to go. I can't even figure out why it was done | |
56 this way in the first place...it's just a historical wierdism. --Stig */ | |
57 call_data = (val ? val->call_data : NULL); | |
58 #endif | |
59 if (val && val->call_data) | |
60 abort(); /* #### - the call_data for the top_level | |
61 "menubar" widget_value used to be passed | |
62 back to the pre_hook. */ | |
63 | |
64 if (instance->info->pre_activate_cb) | |
65 instance->info->pre_activate_cb (w, instance->info->id, call_data); | |
66 } | |
67 | |
68 static void | |
69 pick_hook (Widget w, XtPointer client_data, XtPointer call_data) | |
70 { | |
71 widget_instance* instance = (widget_instance*)client_data; | |
72 widget_value* contents_val = (widget_value*)call_data; | |
73 widget_value* widget_val; | |
74 XtPointer widget_arg; | |
75 LWLIB_ID id; | |
76 lw_callback post_activate_cb; | |
77 | |
78 if (w->core.being_destroyed) | |
79 return; | |
80 | |
81 /* Grab these values before running any functions, in case running | |
82 the selection_cb causes the widget to be destroyed. */ | |
83 id = instance->info->id; | |
84 post_activate_cb = instance->info->post_activate_cb; | |
85 | |
86 widget_val = lw_get_widget_value_for_widget (instance, w); | |
87 widget_arg = widget_val ? widget_val->call_data : NULL; | |
88 | |
89 if (instance->info->selection_cb && | |
90 contents_val && | |
91 contents_val->enabled && | |
92 !contents_val->contents) | |
93 instance->info->selection_cb (w, id, contents_val->call_data); | |
94 | |
95 if (post_activate_cb) | |
96 post_activate_cb (w, id, widget_arg); | |
97 } | |
98 | |
99 | |
100 | |
101 /* creation functions */ | |
102 static Widget | |
103 xlw_create_menubar (widget_instance* instance) | |
104 { | |
105 Widget widget = | |
106 XtVaCreateWidget (instance->info->name, xlwMenuWidgetClass, | |
107 instance->parent, | |
108 XtNmenu, instance->info->val, | |
109 0); | |
110 XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance); | |
111 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance); | |
112 return widget; | |
113 } | |
114 | |
115 static Widget | |
116 xlw_create_popup_menu (widget_instance* instance) | |
117 { | |
118 Widget popup_shell = | |
119 XtCreatePopupShell (instance->info->name, overrideShellWidgetClass, | |
120 instance->parent, NULL, 0); | |
121 | |
122 Widget widget = | |
123 XtVaCreateManagedWidget ("popup", xlwMenuWidgetClass, | |
124 popup_shell, | |
125 XtNmenu, instance->info->val, | |
126 XtNhorizontal, False, | |
127 0); | |
128 | |
129 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance); | |
130 | |
131 return popup_shell; | |
132 } | |
133 #endif /* MENUBARS_LUCID */ | |
134 | |
135 #ifdef SCROLLBARS_LUCID | |
136 static void | |
137 xlw_scrollbar_callback (Widget widget, XtPointer closure, XtPointer call_data) | |
138 { | |
139 widget_instance *instance = (widget_instance *) closure; | |
140 LWLIB_ID id; | |
141 XlwScrollBarCallbackStruct *data = | |
142 (XlwScrollBarCallbackStruct *) call_data; | |
143 scroll_event event_data; | |
144 scrollbar_values *val = | |
145 (scrollbar_values *) instance->info->val->scrollbar_data; | |
146 double percent; | |
147 | |
148 if (!instance || widget->core.being_destroyed) | |
149 return; | |
150 | |
151 id = instance->info->id; | |
152 | |
153 percent = (double) (data->value - 1) / (double) (INT_MAX - 1); | |
154 event_data.slider_value = | |
155 (int) (percent * (double) (val->maximum - val->minimum)) + val->minimum; | |
156 | |
157 if (event_data.slider_value > (val->maximum - val->slider_size)) | |
158 event_data.slider_value = val->maximum - val->slider_size; | |
159 else if (event_data.slider_value < val->minimum) | |
160 event_data.slider_value = val->minimum; | |
161 | |
162 if (data->event) | |
163 { | |
164 switch (data->event->xany.type) | |
165 { | |
166 case KeyPress: | |
167 case KeyRelease: | |
168 event_data.time = data->event->xkey.time; | |
169 break; | |
170 case ButtonPress: | |
171 case ButtonRelease: | |
172 event_data.time = data->event->xbutton.time; | |
173 break; | |
174 case MotionNotify: | |
175 event_data.time = data->event->xmotion.time; | |
176 break; | |
177 case EnterNotify: | |
178 case LeaveNotify: | |
179 event_data.time = data->event->xcrossing.time; | |
180 break; | |
181 default: | |
182 event_data.time = 0; | |
183 break; | |
184 } | |
185 } | |
186 else | |
187 event_data.time = 0; | |
188 | |
189 switch (data->reason) | |
190 { | |
191 case XmCR_DECREMENT: | |
192 event_data.action = SCROLLBAR_LINE_UP; | |
193 break; | |
194 case XmCR_INCREMENT: | |
195 event_data.action = SCROLLBAR_LINE_DOWN; | |
196 break; | |
197 case XmCR_PAGE_DECREMENT: | |
198 event_data.action = SCROLLBAR_PAGE_UP; | |
199 break; | |
200 case XmCR_PAGE_INCREMENT: | |
201 event_data.action = SCROLLBAR_PAGE_DOWN; | |
202 break; | |
203 case XmCR_TO_TOP: | |
204 event_data.action = SCROLLBAR_TOP; | |
205 break; | |
206 case XmCR_TO_BOTTOM: | |
207 event_data.action = SCROLLBAR_BOTTOM; | |
208 break; | |
209 case XmCR_DRAG: | |
210 event_data.action = SCROLLBAR_DRAG; | |
211 break; | |
212 case XmCR_VALUE_CHANGED: | |
213 event_data.action = SCROLLBAR_CHANGE; | |
214 break; | |
215 default: | |
216 event_data.action = SCROLLBAR_CHANGE; | |
217 break; | |
218 } | |
219 | |
220 if (instance->info->pre_activate_cb) | |
221 instance->info->pre_activate_cb (widget, id, (XtPointer) &event_data); | |
222 } | |
223 | |
224 /* #### Does not yet support horizontal scrollbars. */ | |
225 static Widget | |
226 xlw_create_scrollbar (widget_instance *instance, int vertical) | |
227 { | |
228 Arg al[20]; | |
229 int ac = 0; | |
230 Widget scrollbar; | |
231 | |
232 XtSetArg (al[ac], XmNminimum, 1); ac++; | |
233 XtSetArg (al[ac], XmNmaximum, INT_MAX); ac++; | |
234 XtSetArg (al[ac], XmNincrement, 1); ac++; | |
235 XtSetArg (al[ac], XmNpageIncrement, 1); ac++; | |
236 if (vertical) | |
237 { | |
238 XtSetArg (al[ac], XmNorientation, XmVERTICAL); ac++; | |
239 } | |
240 else | |
241 { | |
242 XtSetArg (al[ac], XmNorientation, XmHORIZONTAL); ac++; | |
243 } | |
244 | |
245 scrollbar = | |
246 XtCreateWidget (instance->info->name, xlwScrollBarWidgetClass, instance->parent, al, ac); | |
247 | |
248 XtAddCallback(scrollbar, XmNdecrementCallback, xlw_scrollbar_callback, | |
249 (XtPointer) instance); | |
250 XtAddCallback(scrollbar, XmNdragCallback, xlw_scrollbar_callback, | |
251 (XtPointer) instance); | |
252 XtAddCallback(scrollbar, XmNincrementCallback, xlw_scrollbar_callback, | |
253 (XtPointer) instance); | |
254 XtAddCallback(scrollbar, XmNpageDecrementCallback, xlw_scrollbar_callback, | |
255 (XtPointer) instance); | |
256 XtAddCallback(scrollbar, XmNpageIncrementCallback, xlw_scrollbar_callback, | |
257 (XtPointer) instance); | |
258 XtAddCallback(scrollbar, XmNtoBottomCallback, xlw_scrollbar_callback, | |
259 (XtPointer) instance); | |
260 XtAddCallback(scrollbar, XmNtoTopCallback, xlw_scrollbar_callback, | |
261 (XtPointer) instance); | |
262 XtAddCallback(scrollbar, XmNvalueChangedCallback, xlw_scrollbar_callback, | |
263 (XtPointer) instance); | |
264 | |
265 return scrollbar; | |
266 } | |
267 | |
268 static Widget | |
269 xlw_create_vertical_scrollbar (widget_instance *instance) | |
270 { | |
271 return xlw_create_scrollbar (instance, 1); | |
272 } | |
273 | |
274 static Widget | |
275 xlw_create_horizontal_scrollbar (widget_instance *instance) | |
276 { | |
277 return xlw_create_scrollbar (instance, 0); | |
278 } | |
279 | |
280 static void | |
281 xlw_update_scrollbar (widget_instance *instance, Widget widget, | |
282 widget_value *val) | |
283 { | |
284 if (val->scrollbar_data) | |
285 { | |
286 scrollbar_values *data = val->scrollbar_data; | |
287 int widget_sliderSize, widget_val; | |
288 int new_sliderSize, new_value; | |
289 double percent; | |
290 | |
291 /* | |
292 * First size and position the scrollbar widget. | |
293 */ | |
294 XtVaSetValues (widget, | |
295 XtNx, data->scrollbar_x, | |
296 XtNy, data->scrollbar_y, | |
297 XtNwidth, data->scrollbar_width, | |
298 XtNheight, data->scrollbar_height, | |
299 0); | |
300 | |
301 /* | |
302 * Now the size the scrollbar's slider. | |
303 */ | |
304 | |
305 XtVaGetValues (widget, | |
306 XmNsliderSize, &widget_sliderSize, | |
307 XmNvalue, &widget_val, | |
308 0); | |
309 | |
310 percent = (double) data->slider_size / | |
311 (double) (data->maximum - data->minimum); | |
312 percent = (percent > 1.0 ? 1.0 : percent); | |
313 new_sliderSize = (int) ((double) (INT_MAX - 1) * percent); | |
314 | |
315 percent = (double) (data->slider_position - data->minimum) / | |
316 (double) (data->maximum - data->minimum); | |
317 percent = (percent > 1.0 ? 1.0 : percent); | |
318 new_value = (int) ((double) (INT_MAX - 1) * percent); | |
319 | |
320 if (new_sliderSize > (INT_MAX - 1)) | |
321 new_sliderSize = INT_MAX - 1; | |
322 if (new_sliderSize < 1) | |
323 new_sliderSize = 1; | |
324 | |
325 if (new_value > (INT_MAX - new_sliderSize)) | |
326 new_value = INT_MAX - new_sliderSize; | |
327 else if (new_value < 1) | |
328 new_value = 1; | |
329 | |
330 if (new_sliderSize != widget_sliderSize || new_value != widget_val) | |
331 XlwScrollBarSetValues (widget, new_value, new_sliderSize, 1, 1, False); | |
332 } | |
333 } | |
334 | |
335 #endif /* SCROLLBARS_LUCID */ | |
336 | |
337 widget_creation_entry | |
338 xlw_creation_table [] = | |
339 { | |
340 #ifdef MENUBARS_LUCID | |
341 {"menubar", xlw_create_menubar}, | |
342 {"popup", xlw_create_popup_menu}, | |
343 #endif | |
344 #ifdef SCROLLBARS_LUCID | |
345 {"vertical-scrollbar", xlw_create_vertical_scrollbar}, | |
346 {"horizontal-scrollbar", xlw_create_horizontal_scrollbar}, | |
347 #endif | |
348 {NULL, NULL} | |
349 }; | |
350 | |
351 Boolean | |
352 lw_lucid_widget_p (Widget widget) | |
353 { | |
354 WidgetClass the_class = XtClass (widget); | |
355 #ifdef MENUBARS_LUCID | |
356 if (the_class == xlwMenuWidgetClass) | |
357 return True; | |
358 #endif | |
359 #ifdef SCROLLBARS_LUCID | |
360 if (the_class == xlwScrollBarWidgetClass) | |
361 return True; | |
362 #endif | |
363 #ifdef MENUBARS_LUCID | |
364 if (the_class == overrideShellWidgetClass) | |
365 return | |
366 XtClass (((CompositeWidget)widget)->composite.children [0]) | |
367 == xlwMenuWidgetClass; | |
368 #endif | |
369 return False; | |
370 } | |
371 | |
372 void | |
373 xlw_update_one_widget (widget_instance* instance, Widget widget, | |
374 widget_value* val, Boolean deep_p) | |
375 { | |
376 WidgetClass class; | |
377 | |
378 class = XtClass (widget); | |
379 | |
380 if (0) | |
381 ; | |
382 #ifdef MENUBARS_LUCID | |
383 else if (class == xlwMenuWidgetClass) | |
384 { | |
385 XlwMenuWidget mw; | |
386 if (XtIsShell (widget)) | |
387 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0]; | |
388 else | |
389 mw = (XlwMenuWidget)widget; | |
390 XtVaSetValues (widget, XtNmenu, val, 0); | |
391 } | |
392 #endif | |
393 #ifdef SCROLLBARS_LUCID | |
394 else if (class == xlwScrollBarWidgetClass) | |
395 { | |
396 xlw_update_scrollbar (instance, widget, val); | |
397 } | |
398 #endif | |
399 } | |
400 | |
401 void | |
402 xlw_update_one_value (widget_instance* instance, Widget widget, | |
403 widget_value* val) | |
404 { | |
405 return; | |
406 } | |
407 | |
408 void | |
409 xlw_pop_instance (widget_instance* instance, Boolean up) | |
410 { | |
411 } | |
412 | |
413 #ifdef MENUBARS_LUCID | |
414 void | |
415 xlw_popup_menu (Widget widget, XEvent *event) | |
416 { | |
417 XlwMenuWidget mw; | |
418 | |
419 if (!XtIsShell (widget)) | |
420 return; | |
421 | |
422 if (event->type == ButtonPress || event->type == ButtonRelease) | |
423 { | |
424 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0]; | |
425 xlw_pop_up_menu (mw, (XButtonPressedEvent *)event); | |
426 } | |
427 else | |
428 abort (); | |
429 } | |
430 #endif | |
431 | |
432 /* Destruction of instances */ | |
433 void | |
434 xlw_destroy_instance (widget_instance* instance) | |
435 { | |
436 if (instance->widget) | |
437 XtDestroyWidget (instance->widget); | |
438 } | |
439 |