Update copyright year to 2014 by running admin/update-copyright.
[emacs.git] / lwlib / lwlib-Xlw.c
blob4bc500cac428b2667204b9912f9d327ab65ecf79
1 /* The lwlib interface to "xlwmenu" menus.
3 Copyright (C) 1992 Lucid, Inc.
4 Copyright (C) 1994, 2000-2014 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. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
23 #include <setjmp.h>
24 #include <lisp.h>
26 #include "lwlib-Xlw.h"
27 #include <X11/StringDefs.h>
28 #include <X11/IntrinsicP.h>
29 #include <X11/ObjectP.h>
30 #include <X11/CompositeP.h>
31 #include <X11/Shell.h>
32 #include "xlwmenu.h"
34 #if 0
36 #include <stdio.h>
38 /* Print the complete X resource name of widget WIDGET to stderr.
39 This is sometimes handy to have available. */
41 void
42 x_print_complete_resource_name (Widget widget)
44 int i;
45 String names[100];
47 for (i = 0; i < 100 && widget != NULL; ++i)
49 names[i] = XtName (widget);
50 widget = XtParent (widget);
53 for (--i; i >= 1; --i)
54 fprintf (stderr, "%s.", names[i]);
55 fprintf (stderr, "%s\n", names[0]);
58 #endif /* 0 */
61 \f/* Menu callbacks */
63 /* Callback XtNhighlightCallback for Lucid menus. W is the menu
64 widget, CLIENT_DATA contains a pointer to the widget_instance
65 for the menu, CALL_DATA contains a pointer to the widget_value
66 structure for the highlighted menu item. The latter may be null
67 if there isn't any highlighted menu item. */
69 static void
70 highlight_hook (Widget w, XtPointer client_data, XtPointer call_data)
72 widget_instance *instance = (widget_instance *) client_data;
74 if (instance->info->highlight_cb
75 && !w->core.being_destroyed)
76 instance->info->highlight_cb (w, instance->info->id, call_data);
79 static void
80 enter_hook (Widget w, XtPointer client_data, XtPointer call_data)
82 highlight_hook (w, client_data, call_data);
85 static void
86 leave_hook (Widget w, XtPointer client_data, XtPointer call_data)
88 highlight_hook (w, client_data, NULL);
92 static void
93 pre_hook (Widget w, XtPointer client_data, XtPointer call_data)
95 widget_instance* instance = (widget_instance*)client_data;
96 widget_value* val;
98 if (w->core.being_destroyed)
99 return;
101 val = lw_get_widget_value_for_widget (instance, w);
102 if (instance->info->pre_activate_cb)
103 instance->info->pre_activate_cb (w, instance->info->id,
104 val ? val->call_data : NULL);
107 static void
108 pick_hook (Widget w, XtPointer client_data, XtPointer call_data)
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;
115 if (w->core.being_destroyed)
116 return;
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);
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);
130 \f/* creation functions */
132 static Widget
133 xlw_create_menubar (widget_instance *instance)
135 Widget widget;
136 Arg al[5];
137 int ac = 0;
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
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);
152 XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
153 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
154 XtAddCallback (widget, XtNleaveCallback, leave_hook, (XtPointer)instance);
155 XtAddCallback (widget, XtNenterCallback, enter_hook, (XtPointer)instance);
156 return widget;
159 static Widget
160 xlw_create_popup_menu (widget_instance *instance)
162 Widget popup_shell
163 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
164 instance->parent, NULL, 0);
166 Widget widget;
167 Arg al[2];
168 int ac = 0;
170 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
171 XtSetArg (al[ac], XtNhorizontal, False); ac++;
173 /* This used to use XtVaManagedCreateWidget, but an old Xt version
174 has a bug in XtVaManagedCreateWidget that frees instance->info->name. */
175 widget
176 = XtCreateManagedWidget ("popup", xlwMenuWidgetClass,
177 popup_shell, al, ac);
179 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
180 XtAddCallback (widget, XtNleaveCallback, leave_hook, (XtPointer)instance);
181 XtAddCallback (widget, XtNenterCallback, enter_hook, (XtPointer)instance);
183 return popup_shell;
186 widget_creation_entry
187 xlw_creation_table [] =
189 {"menubar", xlw_create_menubar},
190 {"popup", xlw_create_popup_menu},
191 {NULL, NULL}
194 Boolean
195 lw_lucid_widget_p (Widget widget)
197 WidgetClass the_class = XtClass (widget);
199 if (the_class == xlwMenuWidgetClass)
200 return True;
201 if (the_class == overrideShellWidgetClass)
202 return (XtClass (((CompositeWidget)widget)->composite.children [0])
203 == xlwMenuWidgetClass);
204 return False;
207 void
208 xlw_update_one_widget (widget_instance* instance, Widget widget,
209 widget_value* val, Boolean deep_p)
211 Arg al[1];
213 /* This used to use XtVaSetValues, but some old Xt versions
214 that have a bug in XtVaCreateWidget might have it here too. */
215 XtSetArg (al[0], XtNmenu, instance->info->val);
217 XtSetValues (widget, al, 1);
220 void
221 xlw_update_one_value (widget_instance *instance,
222 Widget widget,
223 widget_value *val)
225 return;
228 void
229 xlw_pop_instance (widget_instance* instance, Boolean up)
233 void
234 xlw_popup_menu (Widget widget, XEvent *event)
236 XlwMenuWidget mw;
238 if (!XtIsShell (widget))
239 return;
241 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
243 if (event)
244 XtCallActionProc ((Widget) mw, "start", event, NULL, 0);
245 else
247 XEvent dummy;
248 XButtonPressedEvent *bd = &dummy.xbutton;
250 bd->type = ButtonPress;
251 bd->serial = 0;
252 bd->send_event = 0;
253 bd->display = XtDisplay (widget);
254 bd->window = XtWindow (XtParent (widget));
255 bd->time = CurrentTime;
256 bd->button = 0;
257 XQueryPointer (bd->display, bd->window, &bd->root,
258 &bd->subwindow, &bd->x_root, &bd->y_root,
259 &bd->x, &bd->y, &bd->state);
261 XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0);
265 \f/* Destruction of instances */
266 void
267 xlw_destroy_instance (widget_instance *instance)
269 if (instance->widget)
270 XtDestroyWidget (instance->widget);