Avoid decode-char in top-level code
[bpt/emacs.git] / lwlib / lwlib-Xlw.c
index 1c56b8e..fc59c56 100644 (file)
@@ -15,7 +15,14 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "../src/lisp.h"
 
 #include "lwlib-Xlw.h"
 #include <X11/StringDefs.h>
@@ -25,9 +32,60 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <X11/Shell.h>
 #include "xlwmenu.h"
 
+#if 0
+
+#include <stdio.h>
+
+/* Print the complete X resource name of widget WIDGET to stderr.
+   This is sometimes handy to have available.  */
+
+void
+x_print_complete_resource_name (widget)
+     Widget widget;
+{
+  int i;
+  String names[100];
+
+  for (i = 0; i < 100 && widget != NULL; ++i)
+    {
+      names[i] = XtName (widget);
+      widget = XtParent (widget);
+    }
+
+  for (--i; i >= 1; --i)
+    fprintf (stderr, "%s.", names[i]);
+  fprintf (stderr, "%s\n", names[0]);
+}
+
+#endif /* 0 */
+
+
 \f/* Menu callbacks */
+
+/* Callback XtNhighlightCallback for Lucid menus.  W is the menu
+   widget, CLIENT_DATA contains a pointer to the widget_instance
+   for the menu, CALL_DATA contains a pointer to the widget_value
+   structure for the highlighted menu item.  The latter may be null
+   if there isn't any highlighted menu item.  */
+
+static void
+highlight_hook (w, client_data, call_data)
+     Widget w;
+     XtPointer client_data;
+     XtPointer call_data;
+{
+  widget_instance *instance = (widget_instance *) client_data;
+
+  if (instance->info->highlight_cb
+      && !w->core.being_destroyed)
+    instance->info->highlight_cb (w, instance->info->id, call_data);
+}
+
 static void
-pre_hook (Widget w, XtPointer client_data, XtPointer call_data)
+pre_hook (w, client_data, call_data)
+     Widget w;
+     XtPointer client_data;
+     XtPointer call_data;
 {
   widget_instance* instance = (widget_instance*)client_data;
   widget_value* val;
@@ -42,7 +100,10 @@ pre_hook (Widget w, XtPointer client_data, XtPointer call_data)
 }
 
 static void
-pick_hook (Widget w, XtPointer client_data, XtPointer call_data)
+pick_hook (w, client_data, call_data)
+     Widget w;
+     XtPointer client_data;
+     XtPointer call_data;
 {
   widget_instance* instance = (widget_instance*)client_data;
   widget_value* contents_val = (widget_value*)call_data;
@@ -65,35 +126,59 @@ pick_hook (Widget w, XtPointer client_data, XtPointer call_data)
 }
 
 \f/* creation functions */
+
 static Widget
-xlw_create_menubar (widget_instance* instance)
+xlw_create_menubar (instance)
+     widget_instance* instance;
 {
-  Widget widget =
-    XtVaCreateWidget (instance->info->name, xlwMenuWidgetClass,
-                     instance->parent,
-                     XtNmenu, instance->info->val,
-                     0);
+  Widget widget;
+  Arg al[5];
+  int ac = 0;
+
+  XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
+#ifdef emacs
+  XtSetArg (al[ac], XtNshowGrip, 0); ac++;
+  XtSetArg (al[ac], XtNresizeToPreferred, 1); ac++;
+  XtSetArg (al[ac], XtNallowResize, 1); ac++;
+#endif
+
+  /* This used to use XtVaCreateWidget, but an old Xt version
+     has a bug in XtVaCreateWidget that frees instance->info->name.  */
+  widget
+    = XtCreateWidget (instance->info->name, xlwMenuWidgetClass,
+                     instance->parent, al, ac);
+
   XtAddCallback (widget, XtNopen, pre_hook, (XtPointer)instance);
   XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
+  XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
+                (XtPointer)instance);
   return widget;
 }
 
 static Widget
-xlw_create_popup_menu (widget_instance* instance)
+xlw_create_popup_menu (instance)
+     widget_instance* instance;
 {
-  Widget popup_shell =
-    XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
-                       instance->parent, NULL, 0);
+  Widget popup_shell
+    XtCreatePopupShell (instance->info->name, overrideShellWidgetClass,
+                         instance->parent, NULL, 0);
   
-  Widget widget = 
-    XtVaCreateManagedWidget ("popup", xlwMenuWidgetClass,
-                            popup_shell,
-                            XtNmenu, instance->info->val,
-                            XtNhorizontal, False,
-                            0);
+  Widget widget;
+  Arg al[2];
+  int ac = 0;
 
-  XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
+  XtSetArg (al[ac], XtNmenu, instance->info->val); ac++;
+  XtSetArg (al[ac], XtNhorizontal, False); ac++;
+
+  /* This used to use XtVaManagedCreateWidget, but an old Xt version
+     has a bug in XtVaManagedCreateWidget that frees instance->info->name.  */
+  widget
+    = XtCreateManagedWidget ("popup", xlwMenuWidgetClass,
+                            popup_shell, al, ac);
 
+  XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance);
+  XtAddCallback (widget, XtNhighlightCallback, highlight_hook,
+                (XtPointer)instance);
   return popup_shell;
 }
 
@@ -106,45 +191,61 @@ xlw_creation_table [] =
 };
 
 Boolean
-lw_lucid_widget_p (Widget widget)
+lw_lucid_widget_p (widget)
+     Widget widget;
 {
   WidgetClass the_class = XtClass (widget);
+
   if (the_class == xlwMenuWidgetClass)
     return True;
   if (the_class == overrideShellWidgetClass)
-    return
-      XtClass (((CompositeWidget)widget)->composite.children [0])
-       == xlwMenuWidgetClass;
+    return (XtClass (((CompositeWidget)widget)->composite.children [0])
+           == xlwMenuWidgetClass);
   return False;
 }
 
 void
-xlw_update_one_widget (widget_instance* instance, Widget widget,
-                      widget_value* val, Boolean deep_p)
+xlw_update_one_widget (instance, widget, val, deep_p)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
+     Boolean deep_p;
 {
   XlwMenuWidget mw;
+  Arg al[1];
 
   if (XtIsShell (widget))
     mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
   else
     mw = (XlwMenuWidget)widget;
-  XtVaSetValues (widget, XtNmenu, val, 0);
+
+  /* This used to use XtVaSetValues, but some old Xt versions
+     that have a bug in XtVaCreateWidget might have it here too.  */
+  XtSetArg (al[0], XtNmenu, instance->info->val);
+
+  XtSetValues (widget, al, 1);
 }
 
 void
-xlw_update_one_value (widget_instance* instance, Widget widget,
-                     widget_value* val)
+xlw_update_one_value (instance, widget, val)
+     widget_instance* instance;
+     Widget widget;
+     widget_value* val;
 {
   return;
 }
 
 void
-xlw_pop_instance (widget_instance* instance, Boolean up)
+xlw_pop_instance (instance, up)
+     widget_instance* instance;
+     Boolean up;
 {
 }
 
 void
-xlw_popup_menu (Widget widget)
+xlw_popup_menu (widget, event)
+     Widget widget;
+     XEvent *event;
 {
   XButtonPressedEvent dummy;
   XlwMenuWidget mw;
@@ -154,23 +255,29 @@ xlw_popup_menu (Widget widget)
 
   mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0];
 
-  dummy.type = ButtonPress;
-  dummy.serial = 0;
-  dummy.send_event = 0;
-  dummy.display = XtDisplay (widget);
-  dummy.window = XtWindow (XtParent (widget));
-  dummy.time = CurrentTime;
-  dummy.button = 0;
-  XQueryPointer (dummy.display, dummy.window, &dummy.root,
-                &dummy.subwindow, &dummy.x_root, &dummy.y_root,
-                &dummy.x, &dummy.y, &dummy.state);
-
-  pop_up_menu (mw, &dummy);
+  if (event)
+    pop_up_menu (mw, (XButtonPressedEvent*) event);
+  else
+    {
+      dummy.type = ButtonPress;
+      dummy.serial = 0;
+      dummy.send_event = 0;
+      dummy.display = XtDisplay (widget);
+      dummy.window = XtWindow (XtParent (widget));
+      dummy.time = CurrentTime;
+      dummy.button = 0;
+      XQueryPointer (dummy.display, dummy.window, &dummy.root,
+                    &dummy.subwindow, &dummy.x_root, &dummy.y_root,
+                    &dummy.x, &dummy.y, &dummy.state);
+
+      pop_up_menu (mw, &dummy);
+    }
 }
 
 \f/* Destruction of instances */
 void
-xlw_destroy_instance (widget_instance* instance)
+xlw_destroy_instance (instance)
+     widget_instance* instance;
 {
   if (instance->widget)
     XtDestroyWidget (instance->widget);