]> code.delx.au - gnu-emacs/blob - lwlib/lwlib-Xlw.c
* xlwmenu.c (xlwMenuActionsList): Install MenuGadgetEscape as an
[gnu-emacs] / lwlib / lwlib-Xlw.c
1 /* The lwlib interface to "xlwmenu" menus.
2 Copyright (C) 1992 Lucid, Inc.
3 Copyright (C) 1994, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of the Lucid Widget Library.
6
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.
11
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.
16
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. */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "lisp.h"
27
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"
35
36 #if 0
37
38 #include <stdio.h>
39
40 /* Print the complete X resource name of widget WIDGET to stderr.
41 This is sometimes handy to have available. */
42
43 void
44 x_print_complete_resource_name (widget)
45 Widget widget;
46 {
47 int i;
48 String names[100];
49
50 for (i = 0; i < 100 && widget != NULL; ++i)
51 {
52 names[i] = XtName (widget);
53 widget = XtParent (widget);
54 }
55
56 for (--i; i >= 1; --i)
57 fprintf (stderr, "%s.", names[i]);
58 fprintf (stderr, "%s\n", names[0]);
59 }
60
61 #endif /* 0 */
62
63
64 \f/* Menu callbacks */
65
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. */
71
72 static void
73 highlight_hook (w, client_data, call_data)
74 Widget w;
75 XtPointer client_data;
76 XtPointer call_data;
77 {
78 widget_instance *instance = (widget_instance *) client_data;
79
80 if (instance->info->highlight_cb
81 && !w->core.being_destroyed)
82 instance->info->highlight_cb (w, instance->info->id, call_data);
83 }
84
85 static void
86 pre_hook (w, client_data, call_data)
87 Widget w;
88 XtPointer client_data;
89 XtPointer call_data;
90 {
91 widget_instance* instance = (widget_instance*)client_data;
92 widget_value* val;
93
94 if (w->core.being_destroyed)
95 return;
96
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);
101 }
102
103 static void
104 pick_hook (w, client_data, call_data)
105 Widget w;
106 XtPointer client_data;
107 XtPointer call_data;
108 {
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;
113
114 if (w->core.being_destroyed)
115 return;
116
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);
121
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);
126
127 }
128
129 \f/* creation functions */
130
131 static Widget
132 xlw_create_menubar (instance)
133 widget_instance* instance;
134 {
135 Widget widget;
136 Arg al[5];
137 int ac = 0;
138
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
145
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);
151
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;
157 }
158
159 static Widget
160 xlw_create_popup_menu (instance)
161 widget_instance* instance;
162 {
163 Widget popup_shell
164 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
165 instance->parent, NULL, 0);
166
167 Widget widget;
168 Arg al[2];
169 int ac = 0;
170
171 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
172 XtSetArg (al[ac], XtNhorizontal, False); ac++;
173
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);
179
180 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
181 XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
182 (XtPointer)instance);
183
184 return popup_shell;
185 }
186
187 widget_creation_entry
188 xlw_creation_table [] =
189 {
190 {"menubar", xlw_create_menubar},
191 {"popup", xlw_create_popup_menu},
192 {NULL, NULL}
193 };
194
195 Boolean
196 lw_lucid_widget_p (widget)
197 Widget widget;
198 {
199 WidgetClass the_class = XtClass (widget);
200
201 if (the_class == xlwMenuWidgetClass)
202 return True;
203 if (the_class == overrideShellWidgetClass)
204 return (XtClass (((CompositeWidget)widget)->composite.children [0])
205 == xlwMenuWidgetClass);
206 return False;
207 }
208
209 void
210 #ifdef PROTOTYPES
211 xlw_update_one_widget (widget_instance* instance, Widget widget,
212 widget_value* val, Boolean deep_p)
213 #else
214 xlw_update_one_widget (instance, widget, val, deep_p)
215 widget_instance* instance;
216 Widget widget;
217 widget_value* val;
218 Boolean deep_p;
219 #endif
220 {
221 Arg al[1];
222
223 /* This used to use XtVaSetValues, but some old Xt versions
224 that have a bug in XtVaCreateWidget might have it here too. */
225 XtSetArg (al[0], XtNmenu, instance->info->val);
226
227 XtSetValues (widget, al, 1);
228 }
229
230 void
231 xlw_update_one_value (instance, widget, val)
232 widget_instance* instance;
233 Widget widget;
234 widget_value* val;
235 {
236 return;
237 }
238
239 void
240 #ifdef PROTOTYPES
241 xlw_pop_instance (widget_instance* instance, Boolean up)
242 #else
243 xlw_pop_instance (instance, up)
244 widget_instance* instance;
245 Boolean up;
246 #endif
247 {
248 }
249
250 void
251 xlw_popup_menu (widget, event)
252 Widget widget;
253 XEvent *event;
254 {
255 XlwMenuWidget mw;
256
257 if (!XtIsShell (widget))
258 return;
259
260 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
261
262 if (event)
263 XtCallActionProc ((Widget) mw, "start", event, NULL, 0);
264 else
265 {
266 XEvent dummy;
267 XButtonPressedEvent *bd = &dummy.xbutton;
268
269 bd->type = ButtonPress;
270 bd->serial = 0;
271 bd->send_event = 0;
272 bd->display = XtDisplay (widget);
273 bd->window = XtWindow (XtParent (widget));
274 bd->time = CurrentTime;
275 bd->button = 0;
276 XQueryPointer (bd->display, bd->window, &bd->root,
277 &bd->subwindow, &bd->x_root, &bd->y_root,
278 &bd->x, &bd->y, &bd->state);
279
280 XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0);
281 }
282 }
283
284 \f/* Destruction of instances */
285 void
286 xlw_destroy_instance (instance)
287 widget_instance* instance;
288 {
289 if (instance->widget)
290 XtDestroyWidget (instance->widget);
291 }
292
293 /* arch-tag: 541e3912-477d-406e-9bf2-dbf2b7ff8c3b
294 (do not change this comment) */