(define-generic-mode): Add argument to specify keywords for defcustom.
[emacs.git] / lwlib / lwlib-Xlw.c
blob248e4e8be74e592b3d3356e00dfc89fdc9364cdd
1 /* The lwlib interface to "xlwmenu" menus.
2 Copyright (C) 1992 Lucid, Inc.
3 Copyright (C) 1994, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of the Lucid Widget Library.
7 The Lucid Widget Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
12 The Lucid Widget Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
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)
45 Widget widget;
47 int i;
48 String names[100];
50 for (i = 0; i < 100 && widget != NULL; ++i)
52 names[i] = XtName (widget);
53 widget = XtParent (widget);
56 for (--i; i >= 1; --i)
57 fprintf (stderr, "%s.", names[i]);
58 fprintf (stderr, "%s\n", names[0]);
61 #endif /* 0 */
64 \f/* Menu callbacks */
66 /* Callback XtNhighlightCallback for Lucid menus. W is the menu
67 widget, CLIENT_DATA contains a pointer to the widget_instance
68 for the menu, CALL_DATA contains a pointer to the widget_value
69 structure for the highlighted menu item. The latter may be null
70 if there isn't any highlighted menu item. */
72 static void
73 highlight_hook (w, client_data, call_data)
74 Widget w;
75 XtPointer client_data;
76 XtPointer call_data;
78 widget_instance *instance = (widget_instance *) client_data;
80 if (instance->info->highlight_cb
81 && !w->core.being_destroyed)
82 instance->info->highlight_cb (w, instance->info->id, call_data);
85 static void
86 pre_hook (w, client_data, call_data)
87 Widget w;
88 XtPointer client_data;
89 XtPointer call_data;
91 widget_instance* instance = (widget_instance*)client_data;
92 widget_value* val;
94 if (w->core.being_destroyed)
95 return;
97 val = lw_get_widget_value_for_widget (instance, w);
98 if (instance->info->pre_activate_cb)
99 instance->info->pre_activate_cb (w, instance->info->id,
100 val ? val->call_data : NULL);
103 static void
104 pick_hook (w, client_data, call_data)
105 Widget w;
106 XtPointer client_data;
107 XtPointer call_data;
109 widget_instance* instance = (widget_instance*)client_data;
110 widget_value* contents_val = (widget_value*)call_data;
111 widget_value* widget_val;
112 XtPointer widget_arg;
114 if (w->core.being_destroyed)
115 return;
117 if (instance->info->selection_cb && contents_val && contents_val->enabled
118 && !contents_val->contents)
119 instance->info->selection_cb (w, instance->info->id,
120 contents_val->call_data);
122 widget_val = lw_get_widget_value_for_widget (instance, w);
123 widget_arg = widget_val ? widget_val->call_data : NULL;
124 if (instance->info->post_activate_cb)
125 instance->info->post_activate_cb (w, instance->info->id, widget_arg);
129 \f/* creation functions */
131 static Widget
132 xlw_create_menubar (instance)
133 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, XtNhighlightCallback, highlight_hook,
155 (XtPointer)instance);
156 return widget;
159 static Widget
160 xlw_create_popup_menu (instance)
161 widget_instance* instance;
163 Widget popup_shell
164 = XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
165 instance->parent, NULL, 0);
167 Widget widget;
168 Arg al[2];
169 int ac = 0;
171 XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
172 XtSetArg (al[ac], XtNhorizontal, False); ac++;
174 /* This used to use XtVaManagedCreateWidget, but an old Xt version
175 has a bug in XtVaManagedCreateWidget that frees instance->info->name. */
176 widget
177 = XtCreateManagedWidget ("popup", xlwMenuWidgetClass,
178 popup_shell, al, ac);
180 XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
181 XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
182 (XtPointer)instance);
184 return popup_shell;
187 widget_creation_entry
188 xlw_creation_table [] =
190 {"menubar", xlw_create_menubar},
191 {"popup", xlw_create_popup_menu},
192 {NULL, NULL}
195 Boolean
196 lw_lucid_widget_p (widget)
197 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 #ifdef PROTOTYPES
211 xlw_update_one_widget (widget_instance* instance, Widget widget,
212 widget_value* val, Boolean deep_p)
213 #else
214 xlw_update_one_widget (instance, widget, val, deep_p)
215 widget_instance* instance;
216 Widget widget;
217 widget_value* val;
218 Boolean deep_p;
219 #endif
221 Arg al[1];
223 /* This used to use XtVaSetValues, but some old Xt versions
224 that have a bug in XtVaCreateWidget might have it here too. */
225 XtSetArg (al[0], XtNmenu, instance->info->val);
227 XtSetValues (widget, al, 1);
230 void
231 xlw_update_one_value (instance, widget, val)
232 widget_instance* instance;
233 Widget widget;
234 widget_value* val;
236 return;
239 void
240 #ifdef PROTOTYPES
241 xlw_pop_instance (widget_instance* instance, Boolean up)
242 #else
243 xlw_pop_instance (instance, up)
244 widget_instance* instance;
245 Boolean up;
246 #endif
250 void
251 xlw_popup_menu (widget, event)
252 Widget widget;
253 XEvent *event;
255 XlwMenuWidget mw;
257 if (!XtIsShell (widget))
258 return;
260 mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
262 if (event)
263 XtCallActionProc ((Widget) mw, "start", event, NULL, 0);
264 else
266 XEvent dummy;
267 XButtonPressedEvent *bd = &dummy.xbutton;
269 bd->type = ButtonPress;
270 bd->serial = 0;
271 bd->send_event = 0;
272 bd->display = XtDisplay (widget);
273 bd->window = XtWindow (XtParent (widget));
274 bd->time = CurrentTime;
275 bd->button = 0;
276 XQueryPointer (bd->display, bd->window, &bd->root,
277 &bd->subwindow, &bd->x_root, &bd->y_root,
278 &bd->x, &bd->y, &bd->state);
280 XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0);
284 \f/* Destruction of instances */
285 void
286 xlw_destroy_instance (instance)
287 widget_instance* instance;
289 if (instance->widget)
290 XtDestroyWidget (instance->widget);
293 /* arch-tag: 541e3912-477d-406e-9bf2-dbf2b7ff8c3b
294 (do not change this comment) */