Fix copying of symlinks.
[emacs.git] / lwlib / lwlib-Xlw.c
bloba4467900f8c694e03016039938f5d37c255e226c
1 /* The lwlib interface to "xlwmenu" menus.
3 Copyright (C) 1992 Lucid, Inc.
4 Copyright (C) 1994, 2000-2012 Free Software Foundation, Inc.
6 This file is part of the Lucid Widget Library.
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.
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.
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. */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include <setjmp.h>
28 #include <lisp.h>
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"
38 #if 0
40 #include <stdio.h>
42 /* Print the complete X resource name of widget WIDGET to stderr.
43 This is sometimes handy to have available. */
45 void
46 x_print_complete_resource_name (Widget widget)
48 int i;
49 String names[100];
51 for (i = 0; i < 100 && widget != NULL; ++i)
53 names[i] = XtName (widget);
54 widget = XtParent (widget);
57 for (--i; i >= 1; --i)
58 fprintf (stderr, "%s.", names[i]);
59 fprintf (stderr, "%s\n", names[0]);
62 #endif /* 0 */
65 \f/* Menu callbacks */
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. */
73 static void
74 highlight_hook (Widget w, XtPointer client_data, XtPointer call_data)
76 widget_instance *instance = (widget_instance *) client_data;
78 if (instance->info->highlight_cb
79 && !w->core.being_destroyed)
80 instance->info->highlight_cb (w, instance->info->id, call_data);
83 static void
84 enter_hook (Widget w, XtPointer client_data, XtPointer call_data)
86 highlight_hook (w, client_data, call_data);
89 static void
90 leave_hook (Widget w, XtPointer client_data, XtPointer call_data)
92 highlight_hook (w, client_data, NULL);
96 static void
97 pre_hook (Widget w, XtPointer client_data, XtPointer call_data)
99 widget_instance* instance = (widget_instance*)client_data;
100 widget_value* val;
102 if (w->core.being_destroyed)
103 return;
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);
111 static void
112 pick_hook (Widget w, XtPointer client_data, XtPointer call_data)
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;
119 if (w->core.being_destroyed)
120 return;
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);
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);
134 \f/* creation functions */
136 static Widget
137 xlw_create_menubar (widget_instance *instance)
139 Widget widget;
140 Arg al[5];
141 int ac = 0;
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
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);
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;
163 static Widget
164 xlw_create_popup_menu (widget_instance *instance)
166 Widget popup_shell
167 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
168 instance->parent, NULL, 0);
170 Widget widget;
171 Arg al[2];
172 int ac = 0;
174 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
175 XtSetArg (al[ac], XtNhorizontal, False); ac++;
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);
183 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
184 XtAddCallback (widget, XtNleaveCallback, leave_hook, (XtPointer)instance);
185 XtAddCallback (widget, XtNenterCallback, enter_hook, (XtPointer)instance);
187 return popup_shell;
190 widget_creation_entry
191 xlw_creation_table [] =
193 {"menubar", xlw_create_menubar},
194 {"popup", xlw_create_popup_menu},
195 {NULL, NULL}
198 Boolean
199 lw_lucid_widget_p (Widget widget)
201 WidgetClass the_class = XtClass (widget);
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;
211 void
212 xlw_update_one_widget (widget_instance* instance, Widget widget,
213 widget_value* val, Boolean deep_p)
215 Arg al[1];
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);
221 XtSetValues (widget, al, 1);
224 void
225 xlw_update_one_value (widget_instance *instance,
226 Widget widget,
227 widget_value *val)
229 return;
232 void
233 xlw_pop_instance (widget_instance* instance, Boolean up)
237 void
238 xlw_popup_menu (Widget widget, XEvent *event)
240 XlwMenuWidget mw;
242 if (!XtIsShell (widget))
243 return;
245 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
247 if (event)
248 XtCallActionProc ((Widget) mw, "start", event, NULL, 0);
249 else
251 XEvent dummy;
252 XButtonPressedEvent *bd = &dummy.xbutton;
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);
265 XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0);
269 \f/* Destruction of instances */
270 void
271 xlw_destroy_instance (widget_instance *instance)
273 if (instance->widget)
274 XtDestroyWidget (instance->widget);