Add 2008 to copyright years.
[bpt/emacs.git] / lwlib / xlwmenu.c
index 1f6cad8..2320dbc 100644 (file)
@@ -1,6 +1,7 @@
 /* Implements a lightweight menubar widget.
-   Copyright (C) 1992 Lucid, Inc.
-   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+Copyright (C) 1992 Lucid, Inc.
+Copyright (C) 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
+  2005, 2006, 2007, 2008  Free Software Foundation, Inc.
 
 This file is part of the Lucid Widget Library.
 
@@ -53,21 +54,8 @@ extern int gray_bitmap_width;
 extern int gray_bitmap_height;
 extern char *gray_bitmap_bits;
 
-/* Defined in xterm.c.  */
-extern int x_alloc_nearest_color_for_widget __P ((Widget, Colormap, XColor*));
-extern int x_alloc_lighter_color_for_widget __P ((Widget, Display*, Colormap,
-                                                 unsigned long *,
-                                                 double, int));
-extern int x_catch_errors __P ((Display*));
-extern void x_uncatch_errors P_ ((Display *, int));
-extern int x_had_errors_p __P ((Display*));
-extern void x_clear_errors __P ((Display*));
-extern unsigned long x_copy_dpy_color __P ((Display *, Colormap,
-                                           unsigned long));
-
-/* Defined in xfaces.c.  */
-extern void x_free_dpy_colors __P ((Display *, Screen *, Colormap,
-                                   unsigned long *pixels, int npixels));
+#include "xterm.h"
+
 #else /* not emacs */
 
 #include <X11/bitmaps/gray>
@@ -174,6 +162,10 @@ xlwMenuResources[] =
      offset(menu.select), XtRCallback, (XtPointer)NULL},
   {XtNhighlightCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
      offset(menu.highlight), XtRCallback, (XtPointer)NULL},
+  {XtNenterCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+     offset(menu.enter), XtRCallback, (XtPointer)NULL},
+  {XtNleaveCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+     offset(menu.leave), XtRCallback, (XtPointer)NULL},
   {XtNmenu, XtCMenu, XtRPointer, sizeof(XtPointer),
      offset(menu.contents), XtRImmediate, (XtPointer)NULL},
   {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
@@ -352,7 +344,7 @@ make_old_stack_space (mw, n)
 }
 
 \f/* Size code */
-int
+static int
 string_width (mw, s)
      XlwMenuWidget mw;
      char *s;
@@ -1199,8 +1191,17 @@ display_menu (mw, level, just_compute_p, highlighted_pos, hit, hit_return,
        {
          if (val->enabled)
            *hit_return = val;
-         else
-           no_return = 1;
+         else 
+            no_return = 1;
+          if (mw->menu.inside_entry != val) 
+            {
+              if (mw->menu.inside_entry)
+                XtCallCallbackList ((Widget)mw, mw->menu.leave,
+                                    (XtPointer) mw->menu.inside_entry);
+              mw->menu.inside_entry = val;
+              XtCallCallbackList ((Widget)mw, mw->menu.enter,
+                                  (XtPointer) mw->menu.inside_entry);
+            }
        }
 
       if (horizontal_p)
@@ -1465,7 +1466,7 @@ motion_event_is_in_menu (mw, ev, level, relative_pos)
   relative_pos->x = ev->x_root - x;
   relative_pos->y = ev->y_root - y;
   return (x - shadow < ev->x_root && ev->x_root < x + ws->width
-         && y - shadow < ev->y_root && ev->y_root < y + ws->height);
+          && y - shadow < ev->y_root && ev->y_root < y + ws->height);
 }
 
 static Boolean
@@ -1478,6 +1479,7 @@ map_event_to_widget_value (mw, ev, val, level)
   int          i;
   XPoint       relative_pos;
   window_state*        ws;
+  int inside = 0;
 
   *val = NULL;
 
@@ -1487,6 +1489,7 @@ map_event_to_widget_value (mw, ev, val, level)
       ws = &mw->menu.windows [i];
       if (ws && motion_event_is_in_menu (mw, ev, i, &relative_pos))
        {
+          inside = 1;
          display_menu (mw, i, True, NULL, &relative_pos, val, NULL, NULL);
 
          if (*val)
@@ -1496,6 +1499,15 @@ map_event_to_widget_value (mw, ev, val, level)
            }
        }
     }
+
+  if (!inside) 
+    {
+      if (mw->menu.inside_entry != NULL) 
+        XtCallCallbackList ((Widget)mw, mw->menu.leave,
+                            (XtPointer) mw->menu.inside_entry);
+      mw->menu.inside_entry = NULL;
+    }
+
   return False;
 }
 
@@ -2088,6 +2100,7 @@ Start (w, ev, params, num_params)
       mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
 
       /* handles the down like a move, slots are compatible */
+      ev->xmotion.is_hint = 0;
       handle_motion_event (mw, &ev->xmotion);
     }
 }
@@ -2425,10 +2438,10 @@ pop_up_menu (mw, event)
   int          borderwidth = mw->menu.shadow_thickness;
   Screen*      screen = XtScreen (mw);
   Display       *display = XtDisplay (mw);
-  int count;
 
   next_release_must_exit = 0;
 
+  mw->menu.inside_entry = NULL;
   XtCallCallbackList ((Widget)mw, mw->menu.open, NULL);
 
   if (XtIsShell (XtParent ((Widget)mw)))
@@ -2472,7 +2485,7 @@ pop_up_menu (mw, event)
     }
 
 #ifdef emacs
-  count = x_catch_errors (display);
+  x_catch_errors (display);
 #endif
   if (XtGrabPointer ((Widget)mw, False,
                      (PointerMotionMask
@@ -2500,9 +2513,10 @@ pop_up_menu (mw, event)
       pointer_grabbed = 0;
       XtUngrabPointer ((Widget)mw, event->time);
     }
-  x_uncatch_errors (display, count);
+  x_uncatch_errors ();
 #endif
 
+  ((XMotionEvent*)event)->is_hint = 0;
   handle_motion_event (mw, (XMotionEvent*)event);
 }