Add todo.
[emacs.git] / lwlib / lwlib-Xlw.c
blob7fbf8bd5f0729546da3b91b59ab90fd91171296b
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, 2007 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 "lisp.h"
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"
37 #if 0
39 #include <stdio.h>
41 /* Print the complete X resource name of widget WIDGET to stderr.
42 This is sometimes handy to have available. */
44 void
45 x_print_complete_resource_name (widget)
46 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 (w, client_data, call_data)
75 Widget w;
76 XtPointer client_data;
77 XtPointer call_data;
79 widget_instance *instance = (widget_instance *) client_data;
81 if (instance->info->highlight_cb
82 && !w->core.being_destroyed)
83 instance->info->highlight_cb (w, instance->info->id, call_data);
86 static void
87 enter_hook (w, client_data, call_data)
88 Widget w;
89 XtPointer client_data;
90 XtPointer call_data;
92 highlight_hook (w, client_data, call_data);
95 static void
96 leave_hook (w, client_data, call_data)
97 Widget w;
98 XtPointer client_data;
99 XtPointer call_data;
101 highlight_hook (w, client_data, NULL);
105 static void
106 pre_hook (w, client_data, call_data)
107 Widget w;
108 XtPointer client_data;
109 XtPointer call_data;
111 widget_instance* instance = (widget_instance*)client_data;
112 widget_value* val;
114 if (w->core.being_destroyed)
115 return;
117 val = lw_get_widget_value_for_widget (instance, w);
118 if (instance->info->pre_activate_cb)
119 instance->info->pre_activate_cb (w, instance->info->id,
120 val ? val->call_data : NULL);
123 static void
124 pick_hook (w, client_data, call_data)
125 Widget w;
126 XtPointer client_data;
127 XtPointer call_data;
129 widget_instance* instance = (widget_instance*)client_data;
130 widget_value* contents_val = (widget_value*)call_data;
131 widget_value* widget_val;
132 XtPointer widget_arg;
134 if (w->core.being_destroyed)
135 return;
137 if (instance->info->selection_cb && contents_val && contents_val->enabled
138 && !contents_val->contents)
139 instance->info->selection_cb (w, instance->info->id,
140 contents_val->call_data);
142 widget_val = lw_get_widget_value_for_widget (instance, w);
143 widget_arg = widget_val ? widget_val->call_data : NULL;
144 if (instance->info->post_activate_cb)
145 instance->info->post_activate_cb (w, instance->info->id, widget_arg);
149 \f/* creation functions */
151 static Widget
152 xlw_create_menubar (instance)
153 widget_instance* instance;
155 Widget widget;
156 Arg al[5];
157 int ac = 0;
159 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
160 #ifdef emacs
161 XtSetArg (al[ac], XtNshowGrip, 0); ac++;
162 XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
163 XtSetArg (al[ac], XtNallowResize, 1); ac++;
164 #endif
166 /* This used to use XtVaCreateWidget, but an old Xt version
167 has a bug in XtVaCreateWidget that frees instance->info->name. */
168 widget
169 = XtCreateWidget (instance->info->name, xlwMenuWidgetClass,
170 instance->parent, al, ac);
172 XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
173 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
174 XtAddCallback (widget, XtNleaveCallback, leave_hook, (XtPointer)instance);
175 XtAddCallback (widget, XtNenterCallback, enter_hook, (XtPointer)instance);
176 return widget;
179 static Widget
180 xlw_create_popup_menu (instance)
181 widget_instance* instance;
183 Widget popup_shell
184 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
185 instance->parent, NULL, 0);
187 Widget widget;
188 Arg al[2];
189 int ac = 0;
191 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
192 XtSetArg (al[ac], XtNhorizontal, False); ac++;
194 /* This used to use XtVaManagedCreateWidget, but an old Xt version
195 has a bug in XtVaManagedCreateWidget that frees instance->info->name. */
196 widget
197 = XtCreateManagedWidget ("popup", xlwMenuWidgetClass,
198 popup_shell, al, ac);
200 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
201 XtAddCallback (widget, XtNleaveCallback, leave_hook, (XtPointer)instance);
202 XtAddCallback (widget, XtNenterCallback, enter_hook, (XtPointer)instance);
204 return popup_shell;
207 widget_creation_entry
208 xlw_creation_table [] =
210 {"menubar", xlw_create_menubar},
211 {"popup", xlw_create_popup_menu},
212 {NULL, NULL}
215 Boolean
216 lw_lucid_widget_p (widget)
217 Widget widget;
219 WidgetClass the_class = XtClass (widget);
221 if (the_class == xlwMenuWidgetClass)
222 return True;
223 if (the_class == overrideShellWidgetClass)
224 return (XtClass (((CompositeWidget)widget)->composite.children [0])
225 == xlwMenuWidgetClass);
226 return False;
229 void
230 #ifdef PROTOTYPES
231 xlw_update_one_widget (widget_instance* instance, Widget widget,
232 widget_value* val, Boolean deep_p)
233 #else
234 xlw_update_one_widget (instance, widget, val, deep_p)
235 widget_instance* instance;
236 Widget widget;
237 widget_value* val;
238 Boolean deep_p;
239 #endif
241 Arg al[1];
243 /* This used to use XtVaSetValues, but some old Xt versions
244 that have a bug in XtVaCreateWidget might have it here too. */
245 XtSetArg (al[0], XtNmenu, instance->info->val);
247 XtSetValues (widget, al, 1);
250 void
251 xlw_update_one_value (instance, widget, val)
252 widget_instance* instance;
253 Widget widget;
254 widget_value* val;
256 return;
259 void
260 #ifdef PROTOTYPES
261 xlw_pop_instance (widget_instance* instance, Boolean up)
262 #else
263 xlw_pop_instance (instance, up)
264 widget_instance* instance;
265 Boolean up;
266 #endif
270 void
271 xlw_popup_menu (widget, event)
272 Widget widget;
273 XEvent *event;
275 XlwMenuWidget mw;
277 if (!XtIsShell (widget))
278 return;
280 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
282 if (event)
283 XtCallActionProc ((Widget) mw, "start", event, NULL, 0);
284 else
286 XEvent dummy;
287 XButtonPressedEvent *bd = &dummy.xbutton;
289 bd->type = ButtonPress;
290 bd->serial = 0;
291 bd->send_event = 0;
292 bd->display = XtDisplay (widget);
293 bd->window = XtWindow (XtParent (widget));
294 bd->time = CurrentTime;
295 bd->button = 0;
296 XQueryPointer (bd->display, bd->window, &bd->root,
297 &bd->subwindow, &bd->x_root, &bd->y_root,
298 &bd->x, &bd->y, &bd->state);
300 XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0);
304 \f/* Destruction of instances */
305 void
306 xlw_destroy_instance (instance)
307 widget_instance* instance;
309 if (instance->widget)
310 XtDestroyWidget (instance->widget);
313 /* arch-tag: 541e3912-477d-406e-9bf2-dbf2b7ff8c3b
314 (do not change this comment) */