Include ../src/lisp.h.
[bpt/emacs.git] / lwlib / lwlib-Xlw.c
CommitLineData
07bf635f
RS
1/* The lwlib interface to "xlwmenu" menus.
2 Copyright (C) 1992 Lucid, Inc.
3
4This file is part of the Lucid Widget Library.
5
6The Lucid Widget Library is free software; you can redistribute it and/or
7modify it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11The Lucid Widget Library is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
07bf635f 20
0f0912e6
PE
21#ifdef HAVE_CONFIG_H
22#include <config.h>
23#endif
24
2f96293d
RS
25#include "../src/lisp.h"
26
07bf635f
RS
27#include "lwlib-Xlw.h"
28#include <X11/StringDefs.h>
29#include <X11/IntrinsicP.h>
30#include <X11/ObjectP.h>
31#include <X11/CompositeP.h>
32#include <X11/Shell.h>
33#include "xlwmenu.h"
34
d3a785ff
GM
35#if 0
36
37#include <stdio.h>
38
39/* Print the complete X resource name of widget WIDGET to stderr.
40 This is sometimes handy to have available. */
41
42void
43x_print_complete_resource_name (widget)
44 Widget widget;
45{
46 int i;
47 String names[100];
48
49 for (i = 0; i < 100 && widget != NULL; ++i)
50 {
51 names[i] = XtName (widget);
52 widget = XtParent (widget);
53 }
54
55 for (--i; i >= 1; --i)
56 fprintf (stderr, "%s.", names[i]);
57 fprintf (stderr, "%s\n", names[0]);
58}
59
60#endif /* 0 */
61
62
07bf635f 63\f/* Menu callbacks */
fa616ec4
GM
64
65/* Callback XtNhighlightCallback for Lucid menus. W is the menu
66 widget, CLIENT_DATA contains a pointer to the widget_instance
67 for the menu, CALL_DATA contains a pointer to the widget_value
68 structure for the highlighted menu item. The latter may be null
69 if there isn't any highlighted menu item. */
70
71static void
72highlight_hook (w, client_data, call_data)
73 Widget w;
74 XtPointer client_data;
75 XtPointer call_data;
76{
77 widget_instance *instance = (widget_instance *) client_data;
78
79 if (instance->info->highlight_cb
80 && !w->core.being_destroyed)
81 instance->info->highlight_cb (w, instance->info->id, call_data);
82}
83
07bf635f 84static void
345a94f9
RS
85pre_hook (w, client_data, call_data)
86 Widget w;
87 XtPointer client_data;
88 XtPointer call_data;
07bf635f
RS
89{
90 widget_instance* instance = (widget_instance*)client_data;
91 widget_value* val;
92
93 if (w->core.being_destroyed)
94 return;
95
96 val = lw_get_widget_value_for_widget (instance, w);
97 if (instance->info->pre_activate_cb)
98 instance->info->pre_activate_cb (w, instance->info->id,
99 val ? val->call_data : NULL);
100}
101
102static void
345a94f9
RS
103pick_hook (w, client_data, call_data)
104 Widget w;
105 XtPointer client_data;
106 XtPointer call_data;
07bf635f
RS
107{
108 widget_instance* instance = (widget_instance*)client_data;
109 widget_value* contents_val = (widget_value*)call_data;
110 widget_value* widget_val;
111 XtPointer widget_arg;
112
113 if (w->core.being_destroyed)
114 return;
115
116 if (instance->info->selection_cb && contents_val && contents_val->enabled
117 && !contents_val->contents)
118 instance->info->selection_cb (w, instance->info->id,
119 contents_val->call_data);
120
121 widget_val = lw_get_widget_value_for_widget (instance, w);
122 widget_arg = widget_val ? widget_val->call_data : NULL;
123 if (instance->info->post_activate_cb)
124 instance->info->post_activate_cb (w, instance->info->id, widget_arg);
125
126}
127
128\f/* creation functions */
0b96f00b 129
07bf635f 130static Widget
345a94f9
RS
131xlw_create_menubar (instance)
132 widget_instance* instance;
07bf635f 133{
9acc68b1 134 Widget widget;
5acc1a62 135 Arg al[5];
c52de5eb 136 int ac = 0;
9acc68b1 137
c52de5eb 138 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
5acc1a62
PR
139#ifdef emacs
140 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
141 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
142 XtSetArg (al[ac], XtNallowResize, 1); ac++;
143#endif
9acc68b1 144
c52de5eb
RS
145 /* This used to use XtVaCreateWidget, but an old Xt version
146 has a bug in XtVaCreateWidget that frees instance->info->name. */
364e6904 147 widget
c52de5eb
RS
148 = XtCreateWidget (instance->info->name, xlwMenuWidgetClass,
149 instance->parent, al, ac);
19240c20 150
07bf635f
RS
151 XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
152 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
fa616ec4
GM
153 XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
154 (XtPointer)instance);
07bf635f
RS
155 return widget;
156}
157
158static Widget
345a94f9
RS
159xlw_create_popup_menu (instance)
160 widget_instance* instance;
07bf635f 161{
364e6904
RS
162 Widget popup_shell
163 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
164 instance->parent, NULL, 0);
07bf635f 165
19240c20 166 Widget widget;
c52de5eb
RS
167 Arg al[2];
168 int ac = 0;
19240c20 169
c52de5eb
RS
170 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
171 XtSetArg (al[ac], XtNhorizontal, False); ac++;
19240c20 172
c52de5eb
RS
173 /* This used to use XtVaManagedCreateWidget, but an old Xt version
174 has a bug in XtVaManagedCreateWidget that frees instance->info->name. */
364e6904 175 widget
c52de5eb
RS
176 = XtCreateManagedWidget ("popup", xlwMenuWidgetClass,
177 popup_shell, al, ac);
19240c20 178
07bf635f 179 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
fa616ec4
GM
180 XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
181 (XtPointer)instance);
07bf635f
RS
182 return popup_shell;
183}
184
185widget_creation_entry
186xlw_creation_table [] =
187{
188 {"menubar", xlw_create_menubar},
189 {"popup", xlw_create_popup_menu},
190 {NULL, NULL}
191};
192
193Boolean
345a94f9
RS
194lw_lucid_widget_p (widget)
195 Widget widget;
07bf635f
RS
196{
197 WidgetClass the_class = XtClass (widget);
364e6904 198
07bf635f
RS
199 if (the_class == xlwMenuWidgetClass)
200 return True;
201 if (the_class == overrideShellWidgetClass)
364e6904
RS
202 return (XtClass (((CompositeWidget)widget)->composite.children [0])
203 == xlwMenuWidgetClass);
07bf635f
RS
204 return False;
205}
206
207void
345a94f9
RS
208xlw_update_one_widget (instance, widget, val, deep_p)
209 widget_instance* instance;
210 Widget widget;
211 widget_value* val;
212 Boolean deep_p;
07bf635f
RS
213{
214 XlwMenuWidget mw;
c52de5eb 215 Arg al[1];
07bf635f
RS
216
217 if (XtIsShell (widget))
218 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
219 else
220 mw = (XlwMenuWidget)widget;
c52de5eb
RS
221
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);
225
226 XtSetValues (widget, al, 1);
07bf635f
RS
227}
228
229void
345a94f9
RS
230xlw_update_one_value (instance, widget, val)
231 widget_instance* instance;
232 Widget widget;
233 widget_value* val;
07bf635f
RS
234{
235 return;
236}
237
238void
345a94f9
RS
239xlw_pop_instance (instance, up)
240 widget_instance* instance;
241 Boolean up;
07bf635f
RS
242{
243}
244
245void
0c7c510c 246xlw_popup_menu (widget, event)
345a94f9 247 Widget widget;
0c7c510c 248 XEvent *event;
07bf635f
RS
249{
250 XButtonPressedEvent dummy;
251 XlwMenuWidget mw;
252
253 if (!XtIsShell (widget))
254 return;
255
256 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
257
0c7c510c 258 if (event)
af5e64bc 259 pop_up_menu (mw, (XButtonPressedEvent*) event);
0c7c510c
RS
260 else
261 {
262 dummy.type = ButtonPress;
263 dummy.serial = 0;
264 dummy.send_event = 0;
265 dummy.display = XtDisplay (widget);
266 dummy.window = XtWindow (XtParent (widget));
267 dummy.time = CurrentTime;
268 dummy.button = 0;
269 XQueryPointer (dummy.display, dummy.window, &dummy.root,
270 &dummy.subwindow, &dummy.x_root, &dummy.y_root,
271 &dummy.x, &dummy.y, &dummy.state);
272
273 pop_up_menu (mw, &dummy);
274 }
07bf635f
RS
275}
276
277\f/* Destruction of instances */
278void
345a94f9
RS
279xlw_destroy_instance (instance)
280 widget_instance* instance;
07bf635f
RS
281{
282 if (instance->widget)
283 XtDestroyWidget (instance->widget);
284}
285