summaryrefslogtreecommitdiffstats
path: root/src/gui_athena.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui_athena.c')
-rw-r--r--src/gui_athena.c2303
1 files changed, 0 insertions, 2303 deletions
diff --git a/src/gui_athena.c b/src/gui_athena.c
deleted file mode 100644
index 8b5af63d1a..0000000000
--- a/src/gui_athena.c
+++ /dev/null
@@ -1,2303 +0,0 @@
-/* vi:set ts=8 sts=4 sw=4 noet:
- *
- * VIM - Vi IMproved by Bram Moolenaar
- * GUI/Motif support by Robert Webb
- * Athena port by Bill Foster
- *
- * Do ":help uganda" in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
- */
-
-#include "vim.h"
-
-#include <X11/StringDefs.h>
-#include <X11/Intrinsic.h>
-#ifdef FEAT_GUI_NEXTAW
-# include <X11/neXtaw/Form.h>
-# include <X11/neXtaw/SimpleMenu.h>
-# include <X11/neXtaw/MenuButton.h>
-# include <X11/neXtaw/SmeBSB.h>
-# include <X11/neXtaw/SmeLine.h>
-# include <X11/neXtaw/Box.h>
-# include <X11/neXtaw/Dialog.h>
-# include <X11/neXtaw/Text.h>
-# include <X11/neXtaw/AsciiText.h>
-# include <X11/neXtaw/Scrollbar.h>
-#else
-# include <X11/Xaw/Form.h>
-# include <X11/Xaw/SimpleMenu.h>
-# include <X11/Xaw/MenuButton.h>
-# include <X11/Xaw/SmeBSB.h>
-# include <X11/Xaw/SmeLine.h>
-# include <X11/Xaw/Box.h>
-# include <X11/Xaw/Dialog.h>
-# include <X11/Xaw/Text.h>
-# include <X11/Xaw/AsciiText.h>
-#endif // FEAT_GUI_NEXTAW
-
-#ifndef FEAT_GUI_NEXTAW
-# include "gui_at_sb.h"
-#endif
-
-extern Widget vimShell;
-
-static Widget vimForm = (Widget)0;
-Widget textArea = (Widget)0;
-#ifdef FEAT_MENU
-static Widget menuBar = (Widget)0;
-static XtIntervalId timer = 0; // 0 = expired, otherwise active
-
-// Used to figure out menu ordering
-static vimmenu_T *a_cur_menu = NULL;
-static Cardinal athena_calculate_ins_pos(Widget);
-
-static void gui_athena_popup_callback(Widget, XtPointer, XtPointer);
-static void gui_athena_delayed_arm_action(Widget, XEvent *, String *,
- Cardinal *);
-static void gui_athena_popdown_submenus_action(Widget, XEvent *,
- String *, Cardinal *);
-static XtActionsRec pullAction[2] = {
- { "menu-delayedpopup", (XtActionProc)gui_athena_delayed_arm_action},
- { "menu-popdownsubmenus", (XtActionProc)gui_athena_popdown_submenus_action}
-};
-#endif
-
-#ifdef FEAT_TOOLBAR
-static void gui_mch_reset_focus(void);
-static Widget toolBar = (Widget)0;
-#endif
-
-#if defined(FEAT_GUI_DIALOG) || defined(FEAT_MENU)
-static void gui_athena_menu_colors(Widget id);
-#endif
-static void gui_athena_scroll_colors(Widget id);
-
-#ifdef FEAT_MENU
-static XtTranslations popupTrans, parentTrans, menuTrans, supermenuTrans;
-static Pixmap pullerBitmap = None;
-static int puller_width = 0;
-#endif
-
-/*
- * Scrollbar callback (XtNjumpProc) for when the scrollbar is dragged with the
- * left or middle mouse button.
- */
- static void
-gui_athena_scroll_cb_jump(
- Widget w UNUSED,
- XtPointer client_data,
- XtPointer call_data)
-{
- scrollbar_T *sb, *sb_info;
- long value;
-
- sb = gui_find_scrollbar((long)client_data);
-
- if (sb == NULL)
- return;
- else if (sb->wp != NULL) // Left or right scrollbar
- {
- /*
- * Careful: need to get scrollbar info out of first (left) scrollbar
- * for window, but keep real scrollbar too because we must pass it to
- * gui_drag_scrollbar().
- */
- sb_info = &sb->wp->w_scrollbars[0];
- }
- else // Bottom scrollbar
- sb_info = sb;
-
- value = (long)(*((float *)call_data) * (float)(sb_info->max + 1) + 0.001);
- if (value > sb_info->max)
- value = sb_info->max;
-
- gui_drag_scrollbar(sb, value, TRUE);
-}
-
-/*
- * Scrollbar callback (XtNscrollProc) for paging up or down with the left or
- * right mouse buttons.
- */
- static void
-gui_athena_scroll_cb_scroll(
- Widget w UNUSED,
- XtPointer client_data,
- XtPointer call_data)
-{
- scrollbar_T *sb, *sb_info;
- long value;
- int data = (int)(long)call_data;
- int page;
-
- sb = gui_find_scrollbar((long)client_data);
-
- if (sb == NULL)
- return;
- if (sb->wp != NULL) // Left or right scrollbar
- {
- /*
- * Careful: need to get scrollbar info out of first (left) scrollbar
- * for window, but keep real scrollbar too because we must pass it to
- * gui_drag_scrollbar().
- */
- sb_info = &sb->wp->w_scrollbars[0];
-
- if (sb_info->size > 5)
- page = sb_info->size - 2; // use two lines of context
- else
- page = sb_info->size;
-#ifdef FEAT_GUI_NEXTAW
- if (data < 0)
- {
- data = (data - gui.char_height + 1) / gui.char_height;
- if (data > -sb_info->size)
- data = -1;
- else
- data = -page;
- }
- else if (data > 0)
- {
- data = (data + gui.char_height - 1) / gui.char_height;
- if (data < sb_info->size)
- data = 1;
- else
- data = page;
- }
-#else
- switch (data)
- {
- case ONE_LINE_DATA: data = 1; break;
- case -ONE_LINE_DATA: data = -1; break;
- case ONE_PAGE_DATA: data = page; break;
- case -ONE_PAGE_DATA: data = -page; break;
- case END_PAGE_DATA: data = sb_info->max; break;
- case -END_PAGE_DATA: data = -sb_info->max; break;
- default: data = 0; break;
- }
-#endif
- }
- else // Bottom scrollbar
- {
- sb_info = sb;
-#ifdef FEAT_GUI_NEXTAW
- if (data < 0)
- {
- data = (data - gui.char_width + 1) / gui.char_width;
- if (data > -sb->size)
- data = -1;
- }
- else if (data > 0)
- {
- data = (data + gui.char_width - 1) / gui.char_width;
- if (data < sb->size)
- data = 1;
- }
-#endif
- if (data < -1) // page-width left
- {
- if (sb->size > 8)
- data = -(sb->size - 5);
- else
- data = -sb->size;
- }
- else if (data > 1) // page-width right
- {
- if (sb->size > 8)
- data = (sb->size - 5);
- else
- data = sb->size;
- }
- }
-
- value = sb_info->value + data;
- if (value > sb_info->max)
- value = sb_info->max;
- else if (value < 0)
- value = 0;
-
- // Update the bottom scrollbar an extra time (why is this needed??)
- if (sb->wp == NULL) // Bottom scrollbar
- gui_mch_set_scrollbar_thumb(sb, value, sb->size, sb->max);
-
- gui_drag_scrollbar(sb, value, FALSE);
-}
-
-/*
- * Create all the Athena widgets necessary.
- */
- void
-gui_x11_create_widgets(void)
-{
- /*
- * We don't have any borders handled internally by the textArea to worry
- * about so only skip over the configured border width.
- */
- gui.border_offset = gui.border_width;
-
- // The form containing all the other widgets
- vimForm = XtVaCreateManagedWidget("vimForm",
- formWidgetClass, vimShell,
- XtNborderWidth, 0,
- NULL);
- gui_athena_scroll_colors(vimForm);
-
-#ifdef FEAT_MENU
- // The top menu bar
- menuBar = XtVaCreateManagedWidget("menuBar",
- boxWidgetClass, vimForm,
- XtNresizable, True,
- XtNtop, XtChainTop,
- XtNbottom, XtChainTop,
- XtNleft, XtChainLeft,
- XtNright, XtChainRight,
- XtNinsertPosition, athena_calculate_ins_pos,
- NULL);
- gui_athena_menu_colors(menuBar);
- if (gui.menu_fg_pixel != INVALCOLOR)
- XtVaSetValues(menuBar, XtNborderColor, gui.menu_fg_pixel, NULL);
-#endif
-
-#ifdef FEAT_TOOLBAR
- // Don't create it Managed, it will be managed when creating the first
- // item. Otherwise an empty toolbar shows up.
- toolBar = XtVaCreateWidget("toolBar",
- boxWidgetClass, vimForm,
- XtNresizable, True,
- XtNtop, XtChainTop,
- XtNbottom, XtChainTop,
- XtNleft, XtChainLeft,
- XtNright, XtChainRight,
- XtNorientation, XtorientHorizontal,
- XtNhSpace, 1,
- XtNvSpace, 3,
- XtNinsertPosition, athena_calculate_ins_pos,
- NULL);
- gui_athena_menu_colors(toolBar);
-#endif
-
- // The text area.
- textArea = XtVaCreateManagedWidget("textArea",
- coreWidgetClass, vimForm,
- XtNresizable, True,
- XtNtop, XtChainTop,
- XtNbottom, XtChainTop,
- XtNleft, XtChainLeft,
- XtNright, XtChainLeft,
- XtNbackground, gui.back_pixel,
- XtNborderWidth, 0,
- NULL);
-
- /*
- * Install the callbacks.
- */
- gui_x11_callbacks(textArea, vimForm);
-
-#ifdef FEAT_MENU
- popupTrans = XtParseTranslationTable(
- "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n"
- "<LeaveWindow>: unhighlight()\n"
- "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n"
- "<Motion>: highlight() menu-delayedpopup()");
- parentTrans = XtParseTranslationTable("<LeaveWindow>: unhighlight()");
- menuTrans = XtParseTranslationTable(
- "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n"
- "<LeaveWindow>: menu-popdownsubmenus() XtMenuPopdown() unhighlight()\n"
- "<BtnUp>: notify() unhighlight()\n"
- "<BtnMotion>: highlight() menu-delayedpopup()");
- supermenuTrans = XtParseTranslationTable(
- "<EnterWindow>: menu-popdownsubmenus() highlight() menu-delayedpopup()\n"
- "<LeaveWindow>: unhighlight()\n"
- "<BtnUp>: menu-popdownsubmenus() XtMenuPopdown() notify() unhighlight()\n"
- "<BtnMotion>: highlight() menu-delayedpopup()");
-
- XtAppAddActions(XtWidgetToApplicationContext(vimForm), pullAction,
- XtNumber(pullAction));
-#endif
-
- // Pretend we don't have input focus, we will get an event if we do.
- gui.in_focus = FALSE;
-}
-
-#ifdef FEAT_MENU
-/*
- * Calculates the Pixmap based on the size of the current menu font.
- */
- static Pixmap
-gui_athena_create_pullright_pixmap(Widget w)
-{
- Pixmap retval;
-#ifdef FONTSET_ALWAYS
- XFontSet font = None;
-#else
- XFontStruct *font = NULL;
-#endif
-
-#ifdef FONTSET_ALWAYS
- if (gui.menu_fontset == NOFONTSET)
-#else
- if (gui.menu_font == NOFONT)
-#endif
- {
- XrmValue from, to;
- WidgetList children;
- Cardinal num_children;
-
-#ifdef FONTSET_ALWAYS
- from.size = strlen(from.addr = XtDefaultFontSet);
- to.addr = (XtPointer)&font;
- to.size = sizeof(XFontSet);
-#else
- from.size = strlen(from.addr = XtDefaultFont);
- to.addr = (XtPointer)&font;
- to.size = sizeof(XFontStruct *);
-#endif
- // Assumption: The menuBar children will use the same font as the
- // pulldown menu items AND they will all be of type
- // XtNfont.
- XtVaGetValues(menuBar, XtNchildren, &children,
- XtNnumChildren, &num_children,
- NULL);
- if (XtConvertAndStore(w ? w :
- (num_children > 0) ? children[0] : menuBar,
- XtRString, &from,
-#ifdef FONTSET_ALWAYS
- XtRFontSet, &to
-#else
- XtRFontStruct, &to
-#endif
- ) == False)
- return None;
- // "font" should now contain data
- }
- else
-#ifdef FONTSET_ALWAYS
- font = (XFontSet)gui.menu_fontset;
-#else
- font = (XFontStruct *)gui.menu_font;
-#endif
-
- {
- int width, height;
- GC draw_gc, undraw_gc;
- XGCValues gc_values;
- XPoint points[3];
-
-#ifdef FONTSET_ALWAYS
- height = fontset_height2(font);
-#else
- height = font->max_bounds.ascent + font->max_bounds.descent;
-#endif
- width = height - 2;
- puller_width = width + 4;
- retval = XCreatePixmap(gui.dpy,DefaultRootWindow(gui.dpy),width,
- height, 1);
- gc_values.foreground = 1;
- gc_values.background = 0;
- draw_gc = XCreateGC(gui.dpy, retval,
- GCForeground | GCBackground,
- &gc_values);
- gc_values.foreground = 0;
- gc_values.background = 1;
- undraw_gc = XCreateGC(gui.dpy, retval,
- GCForeground | GCBackground,
- &gc_values);
- points[0].x = 0;
- points[0].y = 0;
- points[1].x = width - 1;
- points[1].y = (height - 1) / 2;
- points[2].x = 0;
- points[2].y = height - 1;
- XFillRectangle(gui.dpy, retval, undraw_gc, 0, 0, height, height);
- XFillPolygon(gui.dpy, retval, draw_gc, points, XtNumber(points),
- Convex, CoordModeOrigin);
- XFreeGC(gui.dpy, draw_gc);
- XFreeGC(gui.dpy, undraw_gc);
- }
- return retval;
-}
-#endif
-
-/*
- * Called when the GUI is not going to start after all.
- */
- void
-gui_x11_destroy_widgets(void)
-{
- textArea = NULL;
-#ifdef FEAT_MENU
- menuBar = NULL;
-#endif
-#ifdef FEAT_TOOLBAR
- toolBar = NULL;
-#endif
-}
-
-#if defined(FEAT_TOOLBAR) || defined(PROTO)
-# include "gui_x11_pm.h"
-# ifdef HAVE_X11_XPM_H
-# include <X11/xpm.h>
-# endif
-
-static void createXpmImages(char_u *path, char **xpm, Pixmap *sen);
-
-/*
- * Allocated a pixmap for toolbar menu "menu".
- * Return in "sen".
- */
- static void
-get_toolbar_pixmap(vimmenu_T *menu, Pixmap *sen)
-{
- char_u buf[MAXPATHL]; // buffer storing expanded pathname
- char **xpm = NULL; // xpm array
-
- buf[0] = NUL; // start with NULL path
-
- if (menu->iconfile != NULL)
- {
- // Use the "icon=" argument.
- gui_find_iconfile(menu->iconfile, buf, "xpm");
- createXpmImages(buf, NULL, sen);
-
- // If it failed, try using the menu name.
- if (*sen == (Pixmap)0 && gui_find_bitmap(menu->name, buf, "xpm") == OK)
- createXpmImages(buf, NULL, sen);
- if (*sen != (Pixmap)0)
- return;
- }
-
- if (menu->icon_builtin || gui_find_bitmap(menu->name, buf, "xpm") == FAIL)
- {
- if (menu->iconidx >= 0 && menu->iconidx
- < (int)ARRAY_LENGTH(built_in_pixmaps))
- xpm = built_in_pixmaps[menu->iconidx];
- else
- xpm = tb_blank_xpm;
- }
-
- if (xpm != NULL || buf[0] != NUL)
- createXpmImages(buf, xpm, sen);
-}
-
-/*
- * Read an Xpm file, doing color substitutions for the foreground and
- * background colors. If there is an error reading a color xpm file,
- * drop back and read the monochrome file. If successful, create the
- * insensitive Pixmap too.
- */
- static void
-createXpmImages(char_u *path, char **xpm, Pixmap *sen)
-{
- Window rootWindow;
- XpmAttributes attrs;
- XpmColorSymbol color[5] =
- {
- {"none", "none", 0},
- {"iconColor1", NULL, 0},
- {"bottomShadowColor", NULL, 0},
- {"topShadowColor", NULL, 0},
- {"selectColor", NULL, 0}
- };
- int screenNum;
- int status;
- Pixmap mask;
- Pixmap map;
-
- gui_mch_get_toolbar_colors(
- &color[BACKGROUND].pixel,
- &color[FOREGROUND].pixel,
- &color[BOTTOM_SHADOW].pixel,
- &color[TOP_SHADOW].pixel,
- &color[HIGHLIGHT].pixel);
-
- // Setup the color substitution table
- attrs.valuemask = XpmColorSymbols;
- attrs.colorsymbols = color;
- attrs.numsymbols = 5;
-
- screenNum = DefaultScreen(gui.dpy);
- rootWindow = RootWindow(gui.dpy, screenNum);
-
- // Create the "sensitive" pixmap
- if (xpm != NULL)
- status = XpmCreatePixmapFromData(gui.dpy, rootWindow, xpm,
- &map, &mask, &attrs);
- else
- status = XpmReadFileToPixmap(gui.dpy, rootWindow, (char *)path,
- &map, &mask, &attrs);
- if (status == XpmSuccess && map != 0)
- {
- XGCValues gcvalues;
- GC back_gc;
- GC mask_gc;
-
- // Need to create new Pixmaps with the mask applied.
- gcvalues.foreground = color[BACKGROUND].pixel;
- back_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues);
- mask_gc = XCreateGC(gui.dpy, map, GCForeground, &gcvalues);
- XSetClipMask(gui.dpy, mask_gc, mask);
-
- // Create the "sensitive" pixmap.
- *sen = XCreatePixmap(gui.dpy, rootWindow,
- attrs.width, attrs.height,
- DefaultDepth(gui.dpy, screenNum));
- XFillRectangle(gui.dpy, *sen, back_gc, 0, 0,
- attrs.width, attrs.height);
- XCopyArea(gui.dpy, map, *sen, mask_gc, 0, 0,
- attrs.width, attrs.height, 0, 0);
-
- XFreeGC(gui.dpy, back_gc);
- XFreeGC(gui.dpy, mask_gc);
- XFreePixmap(gui.dpy, map);
- }
- else
- *sen = 0;
-
- XpmFreeAttributes(&attrs);
-}
-
- void
-gui_mch_set_toolbar_pos(
- int x,
- int y,
- int w,
- int h)
-{
- Dimension border;
- int height;
-
- if (!XtIsManaged(toolBar)) // nothing to do
- return;
- XtUnmanageChild(toolBar);
- XtVaGetValues(toolBar,
- XtNborderWidth, &border,
- NULL);
- height = h - 2 * border;
- if (height < 0)
- height = 1;
- XtVaSetValues(toolBar,
- XtNhorizDistance, x,
- XtNvertDistance, y,
- XtNwidth, w - 2 * border,
- XtNheight, height,
- NULL);
- XtManageChild(toolBar);
-}
-#endif
-
- void
-gui_mch_set_text_area_pos(
- int x,
- int y,
- int w,
- int h)
-{
- XtUnmanageChild(textArea);
- XtVaSetValues(textArea,
- XtNhorizDistance, x,
- XtNvertDistance, y,
- XtNwidth, w,
- XtNheight, h,
- NULL);
- XtManageChild(textArea);
-#ifdef FEAT_TOOLBAR
- // Give keyboard focus to the textArea instead of the toolbar.
- gui_mch_reset_focus();
-#endif
-}
-
-#ifdef FEAT_TOOLBAR
-/*
- * A toolbar button has been pushed; now reset the input focus
- * such that the user can type page up/down etc. and have the
- * input go to the editor window, not the button
- */
- static void
-gui_mch_reset_focus(void)
-{
- XtSetKeyboardFocus(vimForm, textArea);
-}
-#endif
-
-
- void
-gui_x11_set_back_color(void)
-{
- if (textArea != NULL)
- XtVaSetValues(textArea,
- XtNbackground, gui.back_pixel,
- NULL);
-}
-
-#if defined(FEAT_MENU) || defined(PROTO)
-/*
- * Menu stuff.
- */
-
-static char_u *make_pull_name(char_u * name);
-static Widget get_popup_entry(Widget w);
-static Widget submenu_widget(Widget);
-static Boolean has_submenu(Widget);
-static void gui_mch_submenu_change(vimmenu_T *mp, int colors);
-static void gui_athena_menu_font(Widget id);
-
- void
-gui_mch_enable_menu(int flag)
-{
- if (flag)
- {
- XtManageChild(menuBar);
-# ifdef FEAT_TOOLBAR
- if (XtIsManaged(toolBar))
- {
- XtVaSetValues(toolBar,
- XtNvertDistance, gui.menu_height,
- NULL);
- XtVaSetValues(textArea,
- XtNvertDistance, gui.menu_height + gui.toolbar_height,
- NULL);
- }
-# endif
- }
- else
- {
- XtUnmanageChild(menuBar);
-# ifdef FEAT_TOOLBAR
- if (XtIsManaged(toolBar))
- {
- XtVaSetValues(toolBar,
- XtNvertDistance, 0,
- NULL);
- }
-# endif
- }
-}
-
- void
-gui_mch_set_menu_pos(
- int x,
- int y,
- int w,
- int h)
-{
- Dimension border;
- int height;
-
- XtUnmanageChild(menuBar);
- XtVaGetValues(menuBar, XtNborderWidth, &border, NULL);
- // avoid trouble when there are no menu items, and h is 1
- height = h - 2 * border;
- if (height < 0)
- height = 1;
- XtVaSetValues(menuBar,
- XtNhorizDistance, x,
- XtNvertDistance, y,
- XtNwidth, w - 2 * border,
- XtNheight, height,
- NULL);
- XtManageChild(menuBar);
-}
-
-/*
- * Used to calculate the insertion position of a widget with respect to its
- * neighbors.
- *
- * Valid range of return values is: 0 (beginning of children) to
- * numChildren (end of children).
- */
- static Cardinal
-athena_calculate_ins_pos(Widget widget)
-{
- // Assume that if the parent of the vimmenu_T is NULL, then we can get
- // to this menu by traversing "next", starting at "root_menu".
- //
- // This holds true for popup menus, toolbar, and toplevel menu items.
-
- // Popup menus: "id" is NULL. Only submenu_id is valid
-
- // Menus that are not toplevel: "parent" will be non-NULL, "id" &
- // "submenu_id" will be non-NULL.
-
- // Toplevel menus: "parent" is NULL, id is the widget of the menu item
-
- WidgetList children;
- Cardinal num_children = 0;
- int retval;
- Arg args[2];
- int n = 0;
- int i;
-
- XtSetArg(args[n], XtNchildren, &children); n++;
- XtSetArg(args[n], XtNnumChildren, &num_children); n++;
- XtGetValues(XtParent(widget), args, n);
-
- retval = num_children;
- for (i = 0; i < (int)num_children; ++i)
- {
- Widget current = children[i];
- vimmenu_T *menu = NULL;
-
- for (menu = (a_cur_menu->parent == NULL)
- ? root_menu : a_cur_menu->parent->children;
- menu != NULL;
- menu = menu->next)
- if (current == menu->id
- && a_cur_menu->priority < menu->priority
- && i < retval)
- retval = i;
- }
- return retval;
-}
-
- void
-gui_mch_add_menu(vimmenu_T *menu, int idx UNUSED)
-{
- char_u *pullright_name;
- Dimension height, space, border;
- vimmenu_T *parent = menu->parent;
-
- a_cur_menu = menu;
- if (parent == NULL)
- {
- if (menu_is_popup(menu->dname))
- {
- menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname,
- simpleMenuWidgetClass, vimShell,
- XtNinsertPosition, athena_calculate_ins_pos,
- XtNtranslations, popupTrans,
- NULL);
- gui_athena_menu_colors(menu->submenu_id);
- }
- else if (menu_is_menubar(menu->dname))
- {
- menu->id = XtVaCreateManagedWidget((char *)menu->dname,
- menuButtonWidgetClass, menuBar,
- XtNmenuName, menu->dname,
-#ifdef FONTSET_ALWAYS
- XtNinternational, True,
-#endif
- NULL);
- if (menu->id == (Widget)0)
- return;
- gui_athena_menu_colors(menu->id);
- gui_athena_menu_font(menu->id);
-
- menu->submenu_id = XtVaCreatePopupShell((char *)menu->dname,
- simpleMenuWidgetClass, menu->id,
- XtNinsertPosition, athena_calculate_ins_pos,
- XtNtranslations, supermenuTrans,
- NULL);
- gui_athena_menu_colors(menu->submenu_id);
- gui_athena_menu_font(menu->submenu_id);
-
- // Don't update the menu height when it was set at a fixed value
- if (!gui.menu_height_fixed)
- {
- /*
- * When we add a top-level item to the menu bar, we can figure
- * out how high the menu bar should be.
- */
- XtVaGetValues(menuBar,
- XtNvSpace, &space,
- XtNborderWidth, &border,
- NULL);
- XtVaGetValues(menu->id,
- XtNheight, &height,
- NULL);
- gui.menu_height = height + 2 * (space + border);
- }
- }
- }
- else if (parent->submenu_id != (Widget)0)
- {
- menu->id = XtVaCreateManagedWidget((char *)menu->dname,
- smeBSBObjectClass, parent->submenu_id,
- XtNlabel, menu->dname,
-#ifdef FONTSET_ALWAYS
- XtNinternational, True,
-#endif
- NULL);
- if (menu->id == (Widget)0)
- return;
- if (pullerBitmap == None)
- pullerBitmap = gui_athena_create_pullright_pixmap(menu->id);
-
- XtVaSetValues(menu->id, XtNrightBitmap, pullerBitmap,
- NULL);
- // If there are other menu items that are not pulldown menus,
- // we need to adjust the right margins of those, too.
- {
- WidgetList children;
- Cardinal num_children;
- int i;
-
- XtVaGetValues(parent->submenu_id, XtNchildren, &children,
- XtNnumChildren, &num_children,
- NULL);
- for (i = 0; i < (int)num_children; ++i)
- {
- XtVaSetValues(children[i],
- XtNrightMargin, puller_width,
- NULL);
- }
- }
- gui_athena_menu_colors(menu->id);
- gui_athena_menu_font(menu->id);
-
- pullright_name = make_pull_name(menu->dname);
- menu->submenu_id = XtVaCreatePopupShell((char *)pullright_name,
- simpleMenuWidgetClass, parent->submenu_id,
- XtNtranslations, menuTrans,
- NULL);
- gui_athena_menu_colors(menu->submenu_id);
- gui_athena_menu_font(menu->submenu_id);
- vim_free(pullright_name);
- XtAddCallback(menu->submenu_id, XtNpopupCallback,
- gui_athena_popup_callback, (XtPointer)menu);
-
- if (parent->parent != NULL)
- XtOverrideTranslations(parent->submenu_id, parentTrans);
- }
- a_cur_menu = NULL;
-}
-
-// Used to determine whether a SimpleMenu has pulldown entries.
-//
-// "id" is the parent of the menu items.
-// Ignore widget "ignore" in the pane.
- static Boolean
-gui_athena_menu_has_submenus(Widget id, Widget ignore)
-{
- WidgetList children;
- Cardinal num_children;
- int i;
-
- XtVaGetValues(id, XtNchildren, &children,
- XtNnumChildren, &num_children,
- NULL);
- for (i = 0; i < (int)num_children; ++i)
- {
- if (children[i] == ignore)
- continue;
- if (has_submenu(children[i]))
- return True;
- }
- return False;
-}
-
- static void
-gui_athena_menu_font(Widget id)
-{
-#ifdef FONTSET_ALWAYS
- if (gui.menu_fontset != NOFONTSET)
- {
- if (XtIsManaged(id))
- {
- XtUnmanageChild(id);
- XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL);
- // We should force the widget to recalculate its
- // geometry now.
- XtManageChild(id);
- }
- else
- XtVaSetValues(id, XtNfontSet, gui.menu_fontset, NULL);
- if (has_submenu(id))
- XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL);
- }
-#else
- int managed = FALSE;
-
- if (gui.menu_font != NOFONT)
- {
- if (XtIsManaged(id))
- {
- XtUnmanageChild(id);
- managed = TRUE;
- }
-
-# ifdef FEAT_XFONTSET
- if (gui.fontset != NOFONTSET)
- XtVaSetValues(id, XtNfontSet, gui.menu_font, NULL);
- else
-# endif
- XtVaSetValues(id, XtNfont, gui.menu_font, NULL);
- if (has_submenu(id))
- XtVaSetValues(id, XtNrightBitmap, pullerBitmap, NULL);
-
- // Force the widget to recalculate its geometry now.
- if (managed)
- XtManageChild(id);
- }
-#endif
-}
-
-
- void
-gui_mch_new_menu_font(void)
-{
- Pixmap oldpuller = None;
-
- if (menuBar == (Widget)0)
- return;
-
- if (pullerBitmap != None)
- {
- oldpuller = pullerBitmap;
- pullerBitmap = gui_athena_create_pullright_pixmap(NULL);
- }
- gui_mch_submenu_change(root_menu, FALSE);
-
- {
- // Iterate through the menubar menu items and get the height of
- // each one. The menu bar height is set to the maximum of all
- // the heights.
- vimmenu_T *mp;
- int max_height = 9999;
-
- FOR_ALL_MENUS(mp)
- {
- if (menu_is_menubar(mp->dname))
- {
- Dimension height;
-
- XtVaGetValues(mp->id,
- XtNheight, &height,
- NULL);
- if (height < max_height)
- max_height = height;
- }
- }
- if (max_height != 9999)
- {
- // Don't update the menu height when it was set at a fixed value
- if (!gui.menu_height_fixed)
- {
- Dimension space, border;
-
- XtVaGetValues(menuBar,
- XtNvSpace, &space,
- XtNborderWidth, &border,
- NULL);
- gui.menu_height = max_height + 2 * (space + border);
- }
- }
- }
- // Now, to simulate the window being resized. Only, this
- // will resize the window to its current state.
- //
- // There has to be a better way, but I do not see one at this time.
- // (David Harrison)
- {
- Position w, h;
-
- XtVaGetValues(vimShell,
- XtNwidth, &w,
- XtNheight, &h,
- NULL);
- gui_resize_shell(w, h
-#ifdef FEAT_XIM
- - xim_get_status_area_height()
-#endif
- );
- }
- gui_set_shellsize(FALSE, TRUE, RESIZE_VERT);
- ui_new_shellsize();
- if (oldpuller != None)
- XFreePixmap(gui.dpy, oldpuller);
-}
-
-#if defined(FEAT_BEVAL_GUI) || defined(PROTO)
- void
-gui_mch_new_tooltip_font(void)
-{
-# ifdef FEAT_TOOLBAR
- vimmenu_T *menu;
-
- if (toolBar == (Widget)0)
- return;
-
- menu = gui_find_menu((char_u *)"ToolBar");
- if (menu != NULL)
- gui_mch_submenu_change(menu, FALSE);
-# endif
-}
-
- void
-gui_mch_new_tooltip_colors(void)
-{
-# ifdef FEAT_TOOLBAR
- vimmenu_T *menu;
-
- if (toolBar == (Widget)0)
- return;
-
- menu = gui_find_menu((char_u *)"ToolBar");
- if (menu != NULL)
- gui_mch_submenu_change(menu, TRUE);
-# endif
-}
-#endif
-
- static void
-gui_mch_submenu_change(
- vimmenu_T *menu,
- int colors) // TRUE for colors, FALSE for font
-{
- vimmenu_T *mp;
-
- for (mp = menu; mp != NULL; mp = mp->next)
- {
- if (mp->id != (Widget)0)
- {
- if (colors)
- {
- gui_athena_menu_colors(mp->id);
-#ifdef FEAT_TOOLBAR
- // For a toolbar item: Free the pixmap and allocate a new one,
- // so that the background color is right.
- if (mp->image != (Pixmap)0)
- {
- XFreePixmap(gui.dpy, mp->image);
- get_toolbar_pixmap(mp, &mp->image);
- if (mp->image != (Pixmap)0)
- XtVaSetValues(mp->id, XtNbitmap, mp->image, NULL);
- }
-
-# ifdef FEAT_BEVAL_GUI
- // If we have a tooltip, then we need to change its colors
- if (mp->tip != NULL)
- {
- Arg args[2];
-
- args[0].name = XtNbackground;
- args[0].value = gui.tooltip_bg_pixel;
- args[1].name = XtNforeground;
- args[1].value = gui.tooltip_fg_pixel;
- XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args));
- }
-# endif
-#endif
- }
- else
- {
- gui_athena_menu_font(mp->id);
-#ifdef FEAT_BEVAL_GUI
- // If we have a tooltip, then we need to change its font
- // Assume XtNinternational == True (in createBalloonEvalWindow)
- if (mp->tip != NULL)
- {
- Arg args[1];
-
- args[0].name = XtNfontSet;
- args[0].value = (XtArgVal)gui.tooltip_fontset;
- XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args));
- }
-#endif
- }
- }
-
- if (mp->children != NULL)
- {
- // Set the colors/font for the tear off widget
- if (mp->submenu_id != (Widget)0)
- {
- if (colors)
- gui_athena_menu_colors(mp->submenu_id);
- else
- gui_athena_menu_font(mp->submenu_id);
- }
- // Set the colors for the children
- gui_mch_submenu_change(mp->children, colors);
- }
- }
-}
-
-/*
- * Make a submenu name into a pullright name.
- * Replace '.' by '_', can't include '.' in the submenu name.
- */
- static char_u *
-make_pull_name(char_u * name)
-{
- char_u *pname;
- char_u *p;
-
- pname = vim_strnsave(name, STRLEN(name) + strlen("-pullright"));
- if (pname != NULL)
- {
- strcat((char *)pname, "-pullright");
- while ((p = vim_strchr(pname, '.')) != NULL)
- *p = '_';
- }
- return pname;
-}
-
- void
-gui_mch_add_menu_item(vimmenu_T *menu, int idx UNUSED)
-{
- vimmenu_T *parent = menu->parent;
-
- a_cur_menu = menu;
-# ifdef FEAT_TOOLBAR
- if (menu_is_toolbar(parent->name))
- {
- WidgetClass type;
- int n;
- Arg args[21];
-
- n = 0;
- if (menu_is_separator(menu->name))
- {
- XtSetArg(args[n], XtNlabel, ""); n++;
- XtSetArg(args[n], XtNborderWidth, 0); n++;
- }
- else
- {
- get_toolbar_pixmap(menu, &menu->image);
- XtSetArg(args[n], XtNlabel, menu->dname); n++;
- XtSetArg(args[n], XtNinternalHeight, 1); n++;
- XtSetArg(args[n], XtNinternalWidth, 1); n++;
- XtSetArg(args[n], XtNborderWidth, 1); n++;
- if (menu->image != 0)
- {
- XtSetArg(args[n], XtNbitmap, menu->image); n++;
- }
- }
- XtSetArg(args[n], XtNhighlightThickness, 0); n++;
- type = commandWidgetClass;
- // TODO: figure out the position in the toolbar?
- // This currently works fine for the default toolbar, but
- // what if we add/remove items during later runtime?
-
- // NOTE: "idx" isn't used here. The position is calculated by
- // athena_calculate_ins_pos(). The position it calculates
- // should be equal to "idx".
- // TODO: Could we just store "idx" and use that as the child
- // placement?
-
- if (menu->id == NULL)
- {
- menu->id = XtCreateManagedWidget((char *)menu->dname,
- type, toolBar, args, n);
- XtAddCallback(menu->id,
- XtNcallback, gui_x11_menu_cb, menu);
- }
- else
- XtSetValues(menu->id, args, n);
- gui_athena_menu_colors(menu->id);
-
-#ifdef FEAT_BEVAL_GUI
- gui_mch_menu_set_tip(menu);
-#endif
-
- menu->parent = parent;
- menu->submenu_id = (Widget)0;
- if (!XtIsManaged(toolBar)
- && vim_strchr(p_go, GO_TOOLBAR) != NULL)
- gui_mch_show_toolbar(TRUE);
- gui.toolbar_height = gui_mch_compute_toolbar_height();
- return;
- } // toolbar menu item
-# endif
-
- // Add menu separator
- if (menu_is_separator(menu->name))
- {
- menu->submenu_id = (Widget)0;
- menu->id = XtVaCreateManagedWidget((char *)menu->dname,
- smeLineObjectClass, parent->submenu_id,
- NULL);
- if (menu->id == (Widget)0)
- return;
- gui_athena_menu_colors(menu->id);
- }
- else
- {
- if (parent != NULL && parent->submenu_id != (Widget)0)
- {
- menu->submenu_id = (Widget)0;
- menu->id = XtVaCreateManagedWidget((char *)menu->dname,
- smeBSBObjectClass, parent->submenu_id,
- XtNlabel, menu->dname,
-#ifdef FONTSET_ALWAYS
- XtNinternational, True,
-#endif
- NULL);
- if (menu->id == (Widget)0)
- return;
-
- // If there are other "pulldown" items in this pane, then adjust
- // the right margin to accommoda