X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/362b9d483c714a8fd87966ddbd8686850f870e34..ab1dc14b220747e527d507d40905a24ba5c692d9:/lwlib/xlwmenu.c diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index b6c8c1d90a..c76cb1a3f3 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c @@ -1,7 +1,7 @@ /* 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-2012 Free Software Foundation, Inc. This file is part of the Lucid Widget Library. @@ -22,15 +22,12 @@ Boston, MA 02110-1301, USA. */ /* Created by devin@lucid.com */ -#ifdef HAVE_CONFIG_H #include -#endif #include -#include "lisp.h" +#include #include -#include #include #if (defined __sun) && !(defined SUNOS41) @@ -49,30 +46,18 @@ Boston, MA 02110-1301, USA. */ #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 +#include "bitmaps/gray.xbm" #else /* not emacs */ #include -#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 [] = ": start()\n\ @@ -115,7 +100,7 @@ xlwMenuTranslations [] = : 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? */ @@ -131,14 +116,12 @@ xlwMenuResources[] = 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), @@ -204,7 +187,6 @@ static void Key(Widget w, XEvent *ev, String *params, Cardinal *num_params); 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 [] = @@ -287,7 +269,7 @@ ungrab_all (Widget w, Time ungrabtime) /* Like abort, but remove grabs from widget W before. */ -static void +static _Noreturn void abort_gracefully (Widget w) { if (XtIsShell (XtParent (w))) @@ -1224,9 +1206,9 @@ display_menu (XlwMenuWidget mw, { 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, @@ -1352,6 +1334,7 @@ make_windows_if_needed (XlwMenuWidget mw, int n) #endif set_window_type (windows [i].w, mw); } + XFlush (XtDisplay (mw)); } /* Value is non-zero if WINDOW is part of menu bar widget W. */ @@ -1429,7 +1412,7 @@ fit_to_screen (XlwMenuWidget mw, 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; @@ -1489,7 +1472,7 @@ remap_menubar (XlwMenuWidget mw) 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); @@ -1534,10 +1517,12 @@ remap_menubar (XlwMenuWidget mw) 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); } @@ -1593,9 +1578,9 @@ map_event_to_widget_value (XlwMenuWidget mw, } } - 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; @@ -1613,14 +1598,17 @@ make_drawing_gcs (XlwMenuWidget mw) 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; @@ -1691,8 +1679,10 @@ release_drawing_gcs (XlwMenuWidget mw) 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) @@ -1847,37 +1837,47 @@ release_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; } @@ -1904,8 +1904,8 @@ XlwMenuInitialize (Widget request, Widget w, ArgList args, Cardinal *num_args) 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 @@ -1913,16 +1913,16 @@ XlwMenuInitialize (Widget request, Widget w, ArgList args, Cardinal *num_args) ; 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 (); + } } } @@ -1930,7 +1930,7 @@ XlwMenuInitialize (Widget request, Widget w, ArgList args, Cardinal *num_args) if (mw->menu.fontSet) mw->menu.font_extents = XExtentsOfFontSet (mw->menu.fontSet); #endif - + make_drawing_gcs (mw); make_shadow_gcs (mw); @@ -1966,7 +1966,6 @@ XlwMenuInitialize (Widget request, Widget w, ArgList args, Cardinal *num_args) static void XlwMenuClassInitialize (void) { - xlwmenu_default_font = 0; } static void @@ -2107,12 +2106,12 @@ XlwMenuDestroy (Widget w) 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) @@ -2126,13 +2125,13 @@ XlwMenuDestroy (Widget w) #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 @@ -2142,23 +2141,22 @@ XlwMenuSetValues (Widget current, Widget request, Widget new, { 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 @@ -2168,6 +2166,7 @@ XlwMenuSetValues (Widget current, Widget request, Widget new, #endif ) { + int i; release_drawing_gcs (newmw); make_drawing_gcs (newmw); @@ -2177,7 +2176,7 @@ XlwMenuSetValues (Widget current, Widget request, Widget new, 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. */ @@ -2193,7 +2192,7 @@ XlwMenuSetValues (Widget current, Widget request, Widget new, } #ifdef HAVE_XFT - if (facename_changed (newmw, oldmw)) + if (fontname_changed (newmw, oldmw)) { int i; int screen = XScreenNumberOfScreen (newmw->core.screen); @@ -2218,12 +2217,12 @@ XlwMenuSetValues (Widget current, Widget request, Widget new, #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 @@ -2690,6 +2689,3 @@ pop_up_menu (XlwMenuWidget mw, XButtonPressedEvent *event) ((XMotionEvent*)event)->is_hint = 0; handle_motion_event (mw, (XMotionEvent*)event); } - -/* arch-tag: 657f43dd-dfd0-4cc9-910c-52935f01176e - (do not change this comment) */