/* Implements a lightweight menubar widget.
+
Copyright (C) 1992 Lucid, Inc.
-Copyright (C) 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+Copyright (C) 1994-1995, 1997, 1999-2014 Free Software Foundation, Inc.
This file is part of the Lucid Widget Library.
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, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* Created by devin@lucid.com */
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#include <setjmp.h>
-#include "lisp.h"
+#include <lisp.h>
#include <stdio.h>
-#include <ctype.h>
#include <sys/types.h>
#if (defined __sun) && !(defined SUNOS41)
#ifdef emacs
-/* Defined in xfns.c. When config.h defines `static' as empty, we get
- redefinition errors when gray_bitmap is included more than once, so
- we're referring to the one include in xfns.c here. */
-
-extern int gray_bitmap_width;
-extern int gray_bitmap_height;
-extern char *gray_bitmap_bits;
-
-#include "xterm.h"
+#include <xterm.h>
+#include "bitmaps/gray.xbm"
#else /* not emacs */
#include <X11/bitmaps/gray>
-#define gray_bitmap_width gray_width
-#define gray_bitmap_height gray_height
-#define gray_bitmap_bits gray_bits
#endif /* not emacs */
static int pointer_grabbed;
static XEvent menu_post_event;
-static XFontStruct *xlwmenu_default_font;
-
static char
xlwMenuTranslations [] =
"<BtnDown>: start()\n\
<KeyUp>: key()\n\
";
-/* FIXME: Space should toggle toggleable menu item but not remove the menu
+/* FIXME: Space should toggle togglable menu item but not remove the menu
so you can toggle the next one without entering the menu again. */
/* FIXME: Should ESC close one level of menu structure or the complete menu? */
offset(menu.fontSet), XtRFontSet, NULL},
#endif
#ifdef HAVE_XFT
-#define DEFAULT_FACENAME "Sans-10"
- {XtNfaceName, XtCFaceName, XtRString, sizeof(String),
- offset(menu.faceName), XtRString, DEFAULT_FACENAME},
- {XtNdefaultFace, XtCDefaultFace, XtRInt, sizeof(int),
- offset(menu.default_face), XtRImmediate, (XtPointer)1},
+#define DEFAULT_FONTNAME "Sans-10"
+#else
+#define DEFAULT_FONTNAME "XtDefaultFont"
#endif
- {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
- offset(menu.font), XtRString, "XtDefaultFont"},
+ {XtNfont, XtCFont, XtRString, sizeof(String),
+ offset(menu.fontName), XtRString, DEFAULT_FONTNAME },
{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
offset(menu.foreground), XtRString, "XtDefaultForeground"},
{XtNdisabledForeground, XtCDisabledForeground, XtRPixel, sizeof(Pixel),
static void Nothing(Widget w, XEvent *ev, String *params, Cardinal *num_params);
static int separator_height (enum menu_separator);
static void pop_up_menu (XlwMenuWidget, XButtonPressedEvent *);
-static void abort_gracefully (Widget w) NO_RETURN;
static XtActionsRec
xlwMenuActionsList [] =
/* Like abort, but remove grabs from widget W before. */
-static void
+static _Noreturn void
abort_gracefully (Widget w)
{
if (XtIsShell (XtParent (w)))
{
if (val->enabled)
*hit_return = val;
- else
+ else
no_return = 1;
- if (mw->menu.inside_entry != val)
+ if (mw->menu.inside_entry != val)
{
if (mw->menu.inside_entry)
XtCallCallbackList ((Widget)mw, mw->menu.leave,
#endif
set_window_type (windows [i].w, mw);
}
+ XFlush (XtDisplay (mw));
}
/* Value is non-zero if WINDOW is part of menu bar widget W. */
static void
create_pixmap_for_menu (window_state* ws, XlwMenuWidget mw)
{
- if (ws->pixmap != None)
+ if (ws->pixmap != None)
{
XFreePixmap (XtDisplay (ws->w), ws->pixmap);
ws->pixmap = None;
if (new_selection && !new_selection->enabled)
new_selection = NULL;
- /* Call callback when the hightlighted item changes. */
+ /* Call callback when the highlighted item changes. */
if (old_selection || new_selection)
XtCallCallbackList ((Widget)mw, mw->menu.highlight,
(XtPointer) new_selection);
fit_to_screen (mw, ws, previous_ws, mw->menu.horizontal && i == 1);
- XtVaSetValues (ws->w, XtNwidth, ws->width, XtNheight, ws->height,
- XtNx, ws->x, XtNy, ws->y, NULL);
create_pixmap_for_menu (ws, mw);
+ XtMoveWidget (ws->w, ws->x, ws->y);
XtPopup (ws->w, XtGrabNone);
+ XtResizeWidget (ws->w, ws->width, ws->height,
+ mw->core.border_width);
+ XtResizeWindow (ws->w);
display_menu (mw, i, False, &selection_position, NULL, NULL);
}
}
}
- if (!inside)
+ if (!inside)
{
- if (mw->menu.inside_entry != NULL)
+ if (mw->menu.inside_entry != NULL)
XtCallCallbackList ((Widget)mw, mw->menu.leave,
(XtPointer) mw->menu.inside_entry);
mw->menu.inside_entry = NULL;
XtGCMask mask = GCForeground | GCBackground;
#ifdef HAVE_X_I18N
- if (!mw->menu.fontSet)
+ if (!mw->menu.fontSet && mw->menu.font)
{
xgcv.font = mw->menu.font->fid;
mask |= GCFont;
}
#else
- xgcv.font = mw->menu.font->fid;
- mask |= GCFont;
+ if (mw->menu.font)
+ {
+ xgcv.font = mw->menu.font->fid;
+ mask |= GCFont;
+ }
#endif
xgcv.foreground = mw->menu.foreground;
xgcv.background = mw->core.background_pixel;
mw->menu.background_gc = (GC) -1;
}
+#ifndef emacs
#define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \
? ((unsigned long) (x)) : ((unsigned long) (y)))
+#endif
static void
make_shadow_gcs (XlwMenuWidget mw)
}
#ifdef HAVE_XFT
+static XftFont *
+getDefaultXftFont (XlwMenuWidget mw)
+{
+ int screen = XScreenNumberOfScreen (mw->core.screen);
+ return XftFontOpenName (XtDisplay (mw), screen, DEFAULT_FONTNAME);
+}
+
static int
openXftFont (XlwMenuWidget mw)
{
- char *fname = mw->menu.faceName;
+ char *fname = mw->menu.fontName;
mw->menu.xft_font = 0;
- mw->menu.default_face = fname && strcmp (fname, DEFAULT_FACENAME) == 0;
+ mw->menu.default_face = fname && strcmp (fname, DEFAULT_FONTNAME) == 0;
if (fname && strcmp (fname, "none") != 0)
{
int screen = XScreenNumberOfScreen (mw->core.screen);
int len = strlen (fname), i = len-1;
/* Try to convert Gtk-syntax (Sans 9) to Xft syntax Sans-9. */
- while (i > 0 && isdigit (fname[i]))
+ while (i > 0 && '0' <= fname[i] && fname[i] <= '9')
--i;
if (fname[i] == ' ')
{
- fname = xstrdup (mw->menu.faceName);
+ fname = xstrdup (mw->menu.fontName);
fname[i] = '-';
}
- mw->menu.xft_font = XftFontOpenName (XtDisplay (mw), screen, fname);
- if (!mw->menu.xft_font)
+ mw->menu.font = XLoadQueryFont (XtDisplay (mw), fname);
+ if (!mw->menu.font)
{
- fprintf (stderr, "Can't find font '%s'\n", fname);
- mw->menu.xft_font = XftFontOpenName (XtDisplay (mw), screen,
- DEFAULT_FACENAME);
+ mw->menu.xft_font = XftFontOpenName (XtDisplay (mw), screen, fname);
+ if (!mw->menu.xft_font)
+ {
+ fprintf (stderr, "Can't find font '%s'\n", fname);
+ mw->menu.xft_font = getDefaultXftFont (mw);
+ }
}
}
- if (fname != mw->menu.faceName) free (fname);
+ if (fname != mw->menu.fontName) xfree (fname);
return mw->menu.xft_font != 0;
}
mw->menu.cursor = mw->menu.cursor_shape;
mw->menu.gray_pixmap
- = XCreatePixmapFromBitmapData (display, window, gray_bitmap_bits,
- gray_bitmap_width, gray_bitmap_height,
+ = XCreatePixmapFromBitmapData (display, window, gray_bits,
+ gray_width, gray_height,
(unsigned long)1, (unsigned long)0, 1);
#ifdef HAVE_XFT
;
else
#endif
-
- if (!mw->menu.font)
{
- if (!xlwmenu_default_font)
- xlwmenu_default_font = XLoadQueryFont (display, "fixed");
- mw->menu.font = xlwmenu_default_font;
- if (!mw->menu.font)
+ mw->menu.font = XLoadQueryFont (display, mw->menu.fontName);
+ if (!mw->menu.font)
{
- fprintf (stderr, "Menu font fixed not found, can't continue.\n");
- abort ();
+ mw->menu.font = XLoadQueryFont (display, "fixed");
+ if (!mw->menu.font)
+ {
+ fprintf (stderr, "Menu font fixed not found, can't continue.\n");
+ abort ();
+ }
}
}
if (mw->menu.fontSet)
mw->menu.font_extents = XExtentsOfFontSet (mw->menu.fontSet);
#endif
-
+
make_drawing_gcs (mw);
make_shadow_gcs (mw);
static void
XlwMenuClassInitialize (void)
{
- xlwmenu_default_font = 0;
}
static void
XftFontClose (XtDisplay (mw), mw->menu.xft_font);
#endif
- if (mw->menu.windows [0].pixmap != None)
+ if (mw->menu.windows [0].pixmap != None)
XFreePixmap (XtDisplay (mw), mw->menu.windows [0].pixmap);
/* start from 1 because the one in slot 0 is w->core.window */
for (i = 1; i < mw->menu.windows_length; i++)
{
- if (mw->menu.windows [i].pixmap != None)
+ if (mw->menu.windows [i].pixmap != None)
XFreePixmap (XtDisplay (mw), mw->menu.windows [i].pixmap);
#ifdef HAVE_XFT
if (mw->menu.windows [i].xft_draw)
#ifdef HAVE_XFT
static int
-facename_changed (XlwMenuWidget newmw,
+fontname_changed (XlwMenuWidget newmw,
XlwMenuWidget oldmw)
{
- /* This will fore a new XftFont even if the same string is set.
+ /* This will force a new XftFont even if the same string is set.
This is good, as rendering parameters may have changed and
we just want to do a redisplay. */
- return newmw->menu.faceName != oldmw->menu.faceName;
+ return newmw->menu.fontName != oldmw->menu.fontName;
}
#endif
{
XlwMenuWidget oldmw = (XlwMenuWidget)current;
XlwMenuWidget newmw = (XlwMenuWidget)new;
- Boolean redisplay = False;
- int i;
+ Boolean do_redisplay = False;
if (newmw->menu.contents
&& newmw->menu.contents->contents
&& newmw->menu.contents->contents->change >= VISIBLE_CHANGE)
- redisplay = True;
+ do_redisplay = True;
/* Do redisplay if the contents are entirely eliminated. */
if (newmw->menu.contents
&& newmw->menu.contents->contents == 0
&& newmw->menu.contents->change >= VISIBLE_CHANGE)
- redisplay = True;
+ do_redisplay = True;
if (newmw->core.background_pixel != oldmw->core.background_pixel
|| newmw->menu.foreground != oldmw->menu.foreground
#ifdef HAVE_XFT
- || facename_changed (newmw, oldmw)
+ || fontname_changed (newmw, oldmw)
#endif
#ifdef HAVE_X_I18N
|| newmw->menu.fontSet != oldmw->menu.fontSet
#endif
)
{
+ int i;
release_drawing_gcs (newmw);
make_drawing_gcs (newmw);
newmw->menu.bottom_shadow_color = -1;
make_shadow_gcs (newmw);
- redisplay = True;
+ do_redisplay = True;
if (XtIsRealized (current))
/* If the menu is currently displayed, change the display. */
}
#ifdef HAVE_XFT
- if (facename_changed (newmw, oldmw))
+ if (fontname_changed (newmw, oldmw))
{
int i;
int screen = XScreenNumberOfScreen (newmw->core.screen);
#ifdef HAVE_X_I18N
if (newmw->menu.fontSet != oldmw->menu.fontSet && newmw->menu.fontSet != NULL)
{
- redisplay = True;
+ do_redisplay = True;
newmw->menu.font_extents = XExtentsOfFontSet (newmw->menu.fontSet);
}
#endif
- return redisplay;
+ return do_redisplay;
}
static void
((XMotionEvent*)event)->is_hint = 0;
handle_motion_event (mw, (XMotionEvent*)event);
}
-