diff options
Diffstat (limited to 'src/gui_athena.c')
-rw-r--r-- | src/gui_athena.c | 2303 |
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 |