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