Merge from emacs-24; up to 2012-11-17T22:12:47Z!eggert@cs.ucla.edu
[emacs.git] / lwlib / lwlib-Xlw.c
blobe8c59905ab93a9586b34b8ec3ba12a8715a614d3
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 #include <config.h>
25 #include <setjmp.h>
26 #include <lisp.h>
28 #include "lwlib-Xlw.h"
29 #include <X11/StringDefs.h>
30 #include <X11/IntrinsicP.h>
31 #include <X11/ObjectP.h>
32 #include <X11/CompositeP.h>
33 #include <X11/Shell.h>
34 #include "xlwmenu.h"
36 #if 0
38 #include <stdio.h>
40 /* Print the complete X resource name of widget WIDGET to stderr.
41 This is sometimes handy to have available. */
43 void
44 x_print_complete_resource_name (Widget widget)
46 int i;
47 String names[100];
49 for (i = 0; i < 100 && widget != NULL; ++i)
51 names[i] = XtName (widget);
52 widget = XtParent (widget);
55 for (--i; i >= 1; --i)
56 fprintf (stderr, "%s.", names[i]);
57 fprintf (stderr, "%s\n", names[0]);
60 #endif /* 0 */
63 \f/* Menu callbacks */
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. */
71 static void
72 highlight_hook (Widget w, XtPointer client_data, XtPointer call_data)
74 widget_instance *instance = (widget_instance *) client_data;
76 if (instance->info->highlight_cb
77 && !w->core.being_destroyed)
78 instance->info->highlight_cb (w, instance->info->id, call_data);
81 static void
82 enter_hook (Widget w, XtPointer client_data, XtPointer call_data)
84 highlight_hook (w, client_data, call_data);
87 static void
88 leave_hook (Widget w, XtPointer client_data, XtPointer call_data)
90 highlight_hook (w, client_data, NULL);
94 static void
95 pre_hook (Widget w, XtPointer client_data, XtPointer call_data)
97 widget_instance* instance = (widget_instance*)client_data;
98 widget_value* val;
100 if (w->core.being_destroyed)
101 return;
103 val = lw_get_widget_value_for_widget (instance, w);
104 if (instance->info->pre_activate_cb)
105 instance->info->pre_activate_cb (w, instance->info->id,
106 val ? val->call_data : NULL);
109 static void
110 pick_hook (Widget w, XtPointer client_data, XtPointer call_data)
112 widget_instance* instance = (widget_instance*)client_data;
113 widget_value* contents_val = (widget_value*)call_data;
114 widget_value* widget_val;
115 XtPointer widget_arg;
117 if (w->core.being_destroyed)
118 return;
120 if (instance->info->selection_cb && contents_val && contents_val->enabled
121 && !contents_val->contents)
122 instance->info->selection_cb (w, instance->info->id,
123 contents_val->call_data);
125 widget_val = lw_get_widget_value_for_widget (instance, w);
126 widget_arg = widget_val ? widget_val->call_data : NULL;
127 if (instance->info->post_activate_cb)
128 instance->info->post_activate_cb (w, instance->info->id, widget_arg);
132 \f/* creation functions */
134 static Widget
135 xlw_create_menubar (widget_instance *instance)
137 Widget widget;
138 Arg al[5];
139 int ac = 0;
141 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
142 #ifdef emacs
143 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
144 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
145 XtSetArg (al[ac], XtNallowResize, 1); ac++;
146 #endif
148 /* This used to use XtVaCreateWidget, but an old Xt version
149 has a bug in XtVaCreateWidget that frees instance->info->name. */
150 widget
151 = XtCreateWidget (instance->info->name, xlwMenuWidgetClass,
152 instance->parent, al, ac);
154 XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
155 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
156 XtAddCallback (widget, XtNleaveCallback, leave_hook, (XtPointer)instance);
157 XtAddCallback (widget, XtNenterCallback, enter_hook, (XtPointer)instance);
158 return widget;
161 static Widget
162 xlw_create_popup_menu (widget_instance *instance)
164 Widget popup_shell
165 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
166 instance->parent, NULL, 0);
168 Widget widget;
169 Arg al[2];
170 int ac = 0;
172 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
173 XtSetArg (al[ac], XtNhorizontal, False); ac++;
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);
181 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
182 XtAddCallback (widget, XtNleaveCallback, leave_hook, (XtPointer)instance);
183 XtAddCallback (widget, XtNenterCallback, enter_hook, (XtPointer)instance);
185 return popup_shell;
188 widget_creation_entry
189 xlw_creation_table [] =
191 {"menubar", xlw_create_menubar},
192 {"popup", xlw_create_popup_menu},
193 {NULL, NULL}
196 Boolean
197 lw_lucid_widget_p (Widget widget)
199 WidgetClass the_class = XtClass (widget);
201 if (the_class == xlwMenuWidgetClass)
202 return True;
203 if (the_class == overrideShellWidgetClass)
204 return (XtClass (((CompositeWidget)widget)->composite.children [0])
205 == xlwMenuWidgetClass);
206 return False;
209 void
210 xlw_update_one_widget (widget_instance* instance, Widget widget,
211 widget_value* val, Boolean deep_p)
213 Arg al[1];
215 /* This used to use XtVaSetValues, but some old Xt versions
216 that have a bug in XtVaCreateWidget might have it here too. */
217 XtSetArg (al[0], XtNmenu, instance->info->val);
219 XtSetValues (widget, al, 1);
222 void
223 xlw_update_one_value (widget_instance *instance,
224 Widget widget,
225 widget_value *val)
227 return;
230 void
231 xlw_pop_instance (widget_instance* instance, Boolean up)
235 void
236 xlw_popup_menu (Widget widget, XEvent *event)
238 XlwMenuWidget mw;
240 if (!XtIsShell (widget))
241 return;
243 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
245 if (event)
246 XtCallActionProc ((Widget) mw, "start", event, NULL, 0);
247 else
249 XEvent dummy;
250 XButtonPressedEvent *bd = &dummy.xbutton;
252 bd->type = ButtonPress;
253 bd->serial = 0;
254 bd->send_event = 0;
255 bd->display = XtDisplay (widget);
256 bd->window = XtWindow (XtParent (widget));
257 bd->time = CurrentTime;
258 bd->button = 0;
259 XQueryPointer (bd->display, bd->window, &bd->root,
260 &bd->subwindow, &bd->x_root, &bd->y_root,
261 &bd->x, &bd->y, &bd->state);
263 XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0);
267 \f/* Destruction of instances */
268 void
269 xlw_destroy_instance (widget_instance *instance)
271 if (instance->widget)
272 XtDestroyWidget (instance->widget);