Add Commentary section, minor cleanup of file header.
[emacs.git] / lwlib / lwlib-Xlw.c
blobd0800e0ca0e9abe1f9c0ab4d09f51fbf2e2d71e3
1 /* The lwlib interface to "xlwmenu" menus.
2 Copyright (C) 1992 Lucid, Inc.
3 Copyright (C) 1994, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of the Lucid Widget Library.
7 The Lucid Widget Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
12 The Lucid Widget Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include "lisp.h"
28 #include "lwlib-Xlw.h"
29 #include <X11/StringDefs.h>
30 #include <X11/IntrinsicP.h>
31 #include <X11/ObjectP.h>
32 #include <X11/CompositeP.h>
33 #include <X11/Shell.h>
34 #include "xlwmenu.h"
36 #if 0
38 #include <stdio.h>
40 /* Print the complete X resource name of widget WIDGET to stderr.
41 This is sometimes handy to have available. */
43 void
44 x_print_complete_resource_name (widget)
45 Widget widget;
47 int i;
48 String names[100];
50 for (i = 0; i < 100 && widget != NULL; ++i)
52 names[i] = XtName (widget);
53 widget = XtParent (widget);
56 for (--i; i >= 1; --i)
57 fprintf (stderr, "%s.", names[i]);
58 fprintf (stderr, "%s\n", names[0]);
61 #endif /* 0 */
64 \f/* Menu callbacks */
66 /* Callback XtNhighlightCallback for Lucid menus. W is the menu
67 widget, CLIENT_DATA contains a pointer to the widget_instance
68 for the menu, CALL_DATA contains a pointer to the widget_value
69 structure for the highlighted menu item. The latter may be null
70 if there isn't any highlighted menu item. */
72 static void
73 highlight_hook (w, client_data, call_data)
74 Widget w;
75 XtPointer client_data;
76 XtPointer call_data;
78 widget_instance *instance = (widget_instance *) client_data;
80 if (instance->info->highlight_cb
81 && !w->core.being_destroyed)
82 instance->info->highlight_cb (w, instance->info->id, call_data);
85 static void
86 pre_hook (w, client_data, call_data)
87 Widget w;
88 XtPointer client_data;
89 XtPointer call_data;
91 widget_instance* instance = (widget_instance*)client_data;
92 widget_value* val;
94 if (w->core.being_destroyed)
95 return;
97 val = lw_get_widget_value_for_widget (instance, w);
98 if (instance->info->pre_activate_cb)
99 instance->info->pre_activate_cb (w, instance->info->id,
100 val ? val->call_data : NULL);
103 static void
104 pick_hook (w, client_data, call_data)
105 Widget w;
106 XtPointer client_data;
107 XtPointer call_data;
109 widget_instance* instance = (widget_instance*)client_data;
110 widget_value* contents_val = (widget_value*)call_data;
111 widget_value* widget_val;
112 XtPointer widget_arg;
114 if (w->core.being_destroyed)
115 return;
117 if (instance->info->selection_cb && contents_val && contents_val->enabled
118 && !contents_val->contents)
119 instance->info->selection_cb (w, instance->info->id,
120 contents_val->call_data);
122 widget_val = lw_get_widget_value_for_widget (instance, w);
123 widget_arg = widget_val ? widget_val->call_data : NULL;
124 if (instance->info->post_activate_cb)
125 instance->info->post_activate_cb (w, instance->info->id, widget_arg);
129 \f/* creation functions */
131 static Widget
132 xlw_create_menubar (instance)
133 widget_instance* instance;
135 Widget widget;
136 Arg al[5];
137 int ac = 0;
139 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
140 #ifdef emacs
141 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
142 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
143 XtSetArg (al[ac], XtNallowResize, 1); ac++;
144 #endif
146 /* This used to use XtVaCreateWidget, but an old Xt version
147 has a bug in XtVaCreateWidget that frees instance->info->name. */
148 widget
149 = XtCreateWidget (instance->info->name, xlwMenuWidgetClass,
150 instance->parent, al, ac);
152 XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
153 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
154 XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
155 (XtPointer)instance);
156 return widget;
159 static Widget
160 xlw_create_popup_menu (instance)
161 widget_instance* instance;
163 Widget popup_shell
164 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
165 instance->parent, NULL, 0);
167 Widget widget;
168 Arg al[2];
169 int ac = 0;
171 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
172 XtSetArg (al[ac], XtNhorizontal, False); ac++;
174 /* This used to use XtVaManagedCreateWidget, but an old Xt version
175 has a bug in XtVaManagedCreateWidget that frees instance->info->name. */
176 widget
177 = XtCreateManagedWidget ("popup", xlwMenuWidgetClass,
178 popup_shell, al, ac);
180 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
181 XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
182 (XtPointer)instance);
183 return popup_shell;
186 widget_creation_entry
187 xlw_creation_table [] =
189 {"menubar", xlw_create_menubar},
190 {"popup", xlw_create_popup_menu},
191 {NULL, NULL}
194 Boolean
195 lw_lucid_widget_p (widget)
196 Widget widget;
198 WidgetClass the_class = XtClass (widget);
200 if (the_class == xlwMenuWidgetClass)
201 return True;
202 if (the_class == overrideShellWidgetClass)
203 return (XtClass (((CompositeWidget)widget)->composite.children [0])
204 == xlwMenuWidgetClass);
205 return False;
208 void
209 #ifdef PROTOTYPES
210 xlw_update_one_widget (widget_instance* instance, Widget widget,
211 widget_value* val, Boolean deep_p)
212 #else
213 xlw_update_one_widget (instance, widget, val, deep_p)
214 widget_instance* instance;
215 Widget widget;
216 widget_value* val;
217 Boolean deep_p;
218 #endif
220 Arg al[1];
222 /* This used to use XtVaSetValues, but some old Xt versions
223 that have a bug in XtVaCreateWidget might have it here too. */
224 XtSetArg (al[0], XtNmenu, instance->info->val);
226 XtSetValues (widget, al, 1);
229 void
230 xlw_update_one_value (instance, widget, val)
231 widget_instance* instance;
232 Widget widget;
233 widget_value* val;
235 return;
238 void
239 #ifdef PROTOTYPES
240 xlw_pop_instance (widget_instance* instance, Boolean up)
241 #else
242 xlw_pop_instance (instance, up)
243 widget_instance* instance;
244 Boolean up;
245 #endif
249 void
250 xlw_popup_menu (widget, event)
251 Widget widget;
252 XEvent *event;
254 XButtonPressedEvent dummy;
255 XlwMenuWidget mw;
257 if (!XtIsShell (widget))
258 return;
260 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
262 if (event)
263 pop_up_menu (mw, (XButtonPressedEvent*) event);
264 else
266 dummy.type = ButtonPress;
267 dummy.serial = 0;
268 dummy.send_event = 0;
269 dummy.display = XtDisplay (widget);
270 dummy.window = XtWindow (XtParent (widget));
271 dummy.time = CurrentTime;
272 dummy.button = 0;
273 XQueryPointer (dummy.display, dummy.window, &dummy.root,
274 &dummy.subwindow, &dummy.x_root, &dummy.y_root,
275 &dummy.x, &dummy.y, &dummy.state);
277 pop_up_menu (mw, &dummy);
281 \f/* Destruction of instances */
282 void
283 xlw_destroy_instance (instance)
284 widget_instance* instance;
286 if (instance->widget)
287 XtDestroyWidget (instance->widget);
290 /* arch-tag: 541e3912-477d-406e-9bf2-dbf2b7ff8c3b
291 (do not change this comment) */