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