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