home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / gui_motif.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-24  |  75.5 KB  |  3,091 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *                GUI/Motif support by Robert Webb
  5.  *
  6.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  7.  * Do ":help credits" in Vim to see a list of people who contributed.
  8.  * See README.txt for an overview of the Vim source code.
  9.  */
  10.  
  11. #include <Xm/Form.h>
  12. #include <Xm/RowColumn.h>
  13. #include <Xm/PushB.h>
  14. #include <Xm/Text.h>
  15. #include <Xm/TextF.h>
  16. #include <Xm/Separator.h>
  17. #include <Xm/Label.h>
  18. #include <Xm/CascadeB.h>
  19. #include <Xm/ScrollBar.h>
  20. #include <Xm/MenuShell.h>
  21. #include <Xm/DrawingA.h>
  22. #if (XmVersion >= 1002)
  23. # include <Xm/RepType.h>
  24. #endif
  25. #include <Xm/Frame.h>
  26. #include <Xm/LabelG.h>
  27. #include <Xm/ToggleBG.h>
  28. #include <Xm/SeparatoG.h>
  29.  
  30. #include <X11/keysym.h>
  31. #include <X11/Xatom.h>
  32. #include <X11/StringDefs.h>
  33. #include <X11/Intrinsic.h>
  34.  
  35. #include "vim.h"
  36.  
  37. #ifdef HAVE_X11_XPM_H
  38. # include <X11/xpm.h>
  39. #else
  40. # ifdef HAVE_XM_XPMP_H
  41. #  include <Xm/XpmP.h>
  42. # endif
  43. #endif
  44.  
  45. #if defined(FEAT_GUI_DIALOG) && defined(HAVE_XPM)
  46. # include "../pixmaps/alert.xpm"
  47. # include "../pixmaps/error.xpm"
  48. # include "../pixmaps/generic.xpm"
  49. # include "../pixmaps/info.xpm"
  50. # include "../pixmaps/quest.xpm"
  51. #endif
  52.  
  53. #define MOTIF_POPUP
  54.  
  55. extern Widget vimShell;
  56.  
  57. static Widget vimForm;
  58. static Widget textAreaForm;
  59. Widget textArea;
  60. #ifdef FEAT_TOOLBAR
  61. static Widget toolBarFrame;
  62. static Widget toolBar;
  63. #endif
  64. #ifdef FEAT_FOOTER
  65. static Widget footer;
  66. #endif
  67. #ifdef FEAT_MENU
  68. # if (XmVersion >= 1002)
  69. /* remember the last set value for the tearoff item */
  70. static int tearoff_val = (int)XmTEAR_OFF_ENABLED;
  71. # endif
  72. static Widget menuBar;
  73. #endif
  74.  
  75. static void scroll_cb __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
  76. #ifdef FEAT_TOOLBAR
  77. # if 0
  78. static void toolbar_enter_cb __ARGS((Widget, XtPointer, XEvent *, Boolean *));
  79. static void toolbar_leave_cb __ARGS((Widget, XtPointer, XEvent *, Boolean *));
  80. # endif
  81. # ifdef FEAT_FOOTER
  82. static void toolbarbutton_enter_cb __ARGS((Widget, XtPointer, XEvent *, Boolean *));
  83. static void toolbarbutton_leave_cb __ARGS((Widget, XtPointer, XEvent *, Boolean *));
  84. # endif
  85. static void gui_mch_reset_focus __ARGS((void));
  86. #endif
  87. #ifdef FEAT_FOOTER
  88. static int gui_mch_compute_footer_height __ARGS((void));
  89. #endif
  90. #ifdef WSDEBUG
  91. static void attachDump(Widget, char *);
  92. #endif
  93.  
  94. static void gui_motif_menu_colors __ARGS((Widget id));
  95. static void gui_motif_scroll_colors __ARGS((Widget id));
  96. #ifdef FEAT_MENU
  97. static void gui_motif_menu_fontlist __ARGS((Widget id));
  98. #endif
  99.  
  100. #if (XmVersion >= 1002)
  101. # define STRING_TAG  XmFONTLIST_DEFAULT_TAG
  102. #else
  103. # define STRING_TAG  XmSTRING_DEFAULT_CHARSET
  104. #endif
  105.  
  106. /*
  107.  * Call-back routines.
  108.  */
  109.  
  110. /* ARGSUSED */
  111.     static void
  112. scroll_cb(w, client_data, call_data)
  113.     Widget    w;
  114.     XtPointer    client_data, call_data;
  115. {
  116.     scrollbar_T *sb;
  117.     long    value;
  118.     int        dragging;
  119.  
  120.     sb = gui_find_scrollbar((long)client_data);
  121.  
  122.     value = ((XmScrollBarCallbackStruct *)call_data)->value;
  123.     dragging = (((XmScrollBarCallbackStruct *)call_data)->reason ==
  124.                                   (int)XmCR_DRAG);
  125.     gui_drag_scrollbar(sb, value, dragging);
  126. }
  127.  
  128.  
  129. /*
  130.  * End of call-back routines
  131.  */
  132.  
  133. /*
  134.  * Create all the motif widgets necessary.
  135.  */
  136.     void
  137. gui_x11_create_widgets()
  138. {
  139.     /*
  140.      * Start out by adding the configured border width into the border offset
  141.      */
  142.     gui.border_offset = gui.border_width;
  143.  
  144.     /*
  145.      * Install the tearOffModel resource converter.
  146.      */
  147. #if (XmVersion >= 1002)
  148.     XmRepTypeInstallTearOffModelConverter();
  149. #endif
  150.  
  151.     /* Make sure the "Quit" menu entry of the window manager is ignored */
  152.     XtVaSetValues(vimShell, XmNdeleteResponse, XmDO_NOTHING, NULL);
  153.  
  154.     vimForm = XtVaCreateManagedWidget("vimForm",
  155.     xmFormWidgetClass, vimShell,
  156.     XmNborderWidth, 0,
  157.     XmNhighlightThickness, 0,
  158.     XmNshadowThickness, 0,
  159.     XmNmarginWidth, 0,
  160.     XmNmarginHeight, 0,
  161.     XmNresizePolicy, XmRESIZE_ANY,
  162.     NULL);
  163.     gui_motif_menu_colors(vimForm);
  164.  
  165. #ifdef FEAT_MENU
  166.     {
  167.     Arg al[7]; /* Make sure there is enough room for arguments! */
  168.     int ac = 0;
  169.  
  170. # if (XmVersion >= 1002)
  171.     XtSetArg(al[ac], XmNtearOffModel, tearoff_val); ac++;
  172. # endif
  173.     XtSetArg(al[ac], XmNleftAttachment,  XmATTACH_FORM); ac++;
  174.     XtSetArg(al[ac], XmNtopAttachment,   XmATTACH_FORM); ac++;
  175.     XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  176. # ifndef FEAT_TOOLBAR
  177.     /* Always stick to right hand side. */
  178.     XtSetArg(al[ac], XmNrightOffset, 0); ac++;
  179. # endif
  180.     menuBar = XmCreateMenuBar(vimForm, "menuBar", al, ac);
  181.     XtManageChild(menuBar);
  182.  
  183.     /* Remember the default colors, needed for ":hi clear". */
  184.     XtVaGetValues(menuBar,
  185.         XmNbackground, &gui.menu_def_bg_pixel,
  186.         XmNforeground, &gui.menu_def_fg_pixel,
  187.         NULL);
  188.     gui_motif_menu_colors(menuBar);
  189.     }
  190. #endif
  191.  
  192. #ifdef FEAT_TOOLBAR
  193.     /*
  194.      * Create an empty ToolBar. We should get buttons defined from menu.vim.
  195.      */
  196.     toolBarFrame = XtVaCreateWidget("toolBarFrame",
  197.     xmFrameWidgetClass, vimForm,
  198.     XmNshadowThickness, 0,
  199.     XmNmarginHeight, 0,
  200.     XmNmarginWidth, 0,
  201.     XmNleftAttachment, XmATTACH_FORM,
  202.     XmNrightAttachment, XmATTACH_FORM,
  203.     NULL);
  204.     gui_motif_menu_colors(toolBarFrame);
  205.  
  206.     toolBar = XtVaCreateManagedWidget("toolBar",
  207.     xmRowColumnWidgetClass, toolBarFrame,
  208.     XmNchildType, XmFRAME_WORKAREA_CHILD,
  209.     XmNrowColumnType, XmWORK_AREA,
  210.     XmNorientation, XmHORIZONTAL,
  211.     XmNtraversalOn, False,
  212.     XmNisHomogeneous, False,
  213.     XmNpacking, XmPACK_TIGHT,
  214.     XmNspacing, 0,
  215.     XmNshadowThickness, 0,
  216.     XmNhighlightThickness, 0,
  217.     XmNmarginHeight, 0,
  218.     XmNmarginWidth, 0,
  219.     XmNadjustLast, True,
  220.     NULL);
  221.     gui_motif_menu_colors(toolBar);
  222.  
  223. # if 0    /* these don't work, because of the XmNtraversalOn above. */
  224.     XtAddEventHandler(toolBar, EnterWindowMask, False,
  225.         toolbar_enter_cb, NULL);
  226.     XtAddEventHandler(toolBar, LeaveWindowMask, False,
  227.         toolbar_leave_cb, NULL);
  228. # endif
  229. #endif
  230.  
  231.     textAreaForm = XtVaCreateManagedWidget("textAreaForm",
  232.     xmFormWidgetClass, vimForm,
  233.     XmNleftAttachment, XmATTACH_FORM,
  234.     XmNrightAttachment, XmATTACH_FORM,
  235.     XmNbottomAttachment, XmATTACH_FORM,
  236.     XmNtopAttachment, XmATTACH_FORM,
  237.     XmNmarginWidth, 0,
  238.     XmNmarginHeight, 0,
  239.     XmNresizePolicy, XmRESIZE_ANY,
  240.     NULL);
  241.     gui_motif_scroll_colors(textAreaForm);
  242.  
  243.     textArea = XtVaCreateManagedWidget("textArea",
  244.     xmDrawingAreaWidgetClass, textAreaForm,
  245.     XmNforeground, gui.norm_pixel,
  246.     XmNbackground, gui.back_pixel,
  247.     XmNleftAttachment, XmATTACH_FORM,
  248.     XmNtopAttachment, XmATTACH_FORM,
  249.     XmNrightAttachment, XmATTACH_FORM,
  250.     XmNbottomAttachment, XmATTACH_FORM,
  251.  
  252.     /*
  253.      * These take some control away from the user, but avoids making them
  254.      * add resources to get a decent looking setup.
  255.      */
  256.     XmNborderWidth, 0,
  257.     XmNhighlightThickness, 0,
  258.     XmNshadowThickness, 0,
  259.     NULL);
  260.  
  261. #ifdef FEAT_FOOTER
  262.     /*
  263.      * Create the Footer.
  264.      */
  265.     footer = XtVaCreateWidget("footer",
  266.     xmLabelGadgetClass, vimForm,
  267.     XmNalignment, XmALIGNMENT_BEGINNING,
  268.     XmNmarginHeight, 0,
  269.     XmNmarginWidth, 0,
  270.     XmNtraversalOn, False,
  271.     XmNrecomputeSize, False,
  272.     XmNleftAttachment, XmATTACH_FORM,
  273.     XmNleftOffset, 5,
  274.     XmNrightAttachment, XmATTACH_FORM,
  275.     XmNbottomAttachment, XmATTACH_FORM,
  276.     NULL);
  277.     gui_mch_set_footer((char_u *) "");
  278. #endif
  279.  
  280.     /*
  281.      * Install the callbacks.
  282.      */
  283.     gui_x11_callbacks(textArea, vimForm);
  284.  
  285.     /* Pretend we don't have input focus, we will get an event if we do. */
  286.     gui.in_focus = FALSE;
  287. }
  288.  
  289. /*
  290.  * Called when the GUI is not going to start after all.
  291.  */
  292.     void
  293. gui_x11_destroy_widgets()
  294. {
  295.     textArea = NULL;
  296. #ifdef FEAT_MENU
  297.     menuBar = NULL;
  298. #endif
  299. }
  300.  
  301. /*ARGSUSED*/
  302.     void
  303. gui_mch_set_text_area_pos(x, y, w, h)
  304.     int        x;
  305.     int        y;
  306.     int        w;
  307.     int        h;
  308. {
  309. #ifdef FEAT_TOOLBAR
  310.     /* Give keyboard focus to the textArea instead of the toolbar. */
  311.     gui_mch_reset_focus();
  312. #endif
  313. }
  314.  
  315.     void
  316. gui_x11_set_back_color()
  317. {
  318.     if (textArea != NULL)
  319. #if (XmVersion >= 1002)
  320.     XmChangeColor(textArea, gui.back_pixel);
  321. #else
  322.     XtVaSetValues(textArea,
  323.           XmNbackground, gui.back_pixel,
  324.           NULL);
  325. #endif
  326. }
  327.  
  328. /*
  329.  * Manage dialog centered on pointer. This could be used by the Athena code as
  330.  * well.
  331.  */
  332. static void manage_centered __ARGS((Widget dialog_child));
  333.  
  334. static void
  335. manage_centered(dialog_child)
  336.     Widget dialog_child;
  337. {
  338.     Widget shell = XtParent(dialog_child);
  339.     Window root, child;
  340.     unsigned int mask;
  341.     unsigned int width, height, border_width, depth;
  342.     int x, y, win_x, win_y, maxX, maxY;
  343.     Boolean mappedWhenManaged;
  344.  
  345.     /* Temporarily set value of XmNmappedWhenManaged
  346.        to stop the dialog from popping up right away */
  347.     XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, 0);
  348.     XtVaSetValues(shell, XmNmappedWhenManaged, False, 0);
  349.  
  350.     XtManageChild(dialog_child);
  351.  
  352.     /* Get the pointer position (x, y) */
  353.     XQueryPointer(XtDisplay(shell), XtWindow(shell), &root, &child,
  354.           &x, &y, &win_x, &win_y, &mask);
  355.  
  356.     /* Translate the pointer position (x, y) into a position for the new
  357.        window that will place the pointer at its center */
  358.     XGetGeometry(XtDisplay(shell), XtWindow(shell), &root, &win_x, &win_y,
  359.          &width, &height, &border_width, &depth);
  360.     width += 2 * border_width;
  361.     height += 2 * border_width;
  362.     x -= width / 2;
  363.     y -= height / 2;
  364.  
  365.     /* Ensure that the dialog remains on screen */
  366.     maxX = XtScreen(shell)->width - width;
  367.     maxY = XtScreen(shell)->height - height;
  368.     if (x < 0)
  369.     x = 0;
  370.     if (x > maxX)
  371.     x = maxX;
  372.     if (y < 0)
  373.     y = 0;
  374.     if (y > maxY)
  375.     y = maxY;
  376.  
  377.     /* Set desired window position in the DialogShell */
  378.     XtVaSetValues(shell, XmNx, x, XmNy, y, NULL);
  379.  
  380.     /* Map the widget */
  381.     XtMapWidget(shell);
  382.  
  383.     /* Restore the value of XmNmappedWhenManaged */
  384.     XtVaSetValues(shell, XmNmappedWhenManaged, mappedWhenManaged, 0);
  385. }
  386.  
  387. #if defined(FEAT_MENU) || defined(FEAT_SUN_WORKSHOP) \
  388.     || defined(FEAT_GUI_DIALOG) || defined(PROTO)
  389.  
  390. /*
  391.  * Encapsulate the way an XmFontList is created.
  392.  */
  393.     XmFontList
  394. gui_motif_create_fontlist(font)
  395.     XFontStruct    *font;
  396. {
  397.     XmFontList font_list;
  398.  
  399. # if (XmVersion <= 1001)
  400.     /* Motif 1.1 method */
  401.     font_list = XmFontListCreate(font, STRING_TAG);
  402. # else
  403.     /* Motif 1.2 method */
  404.     XmFontListEntry font_list_entry;
  405.  
  406.     font_list_entry = XmFontListEntryCreate(STRING_TAG, XmFONT_IS_FONT,
  407.                         (XtPointer)font);
  408.     font_list = XmFontListAppendEntry(NULL, font_list_entry);
  409.     XmFontListEntryFree(&font_list_entry);
  410. # endif
  411.     return font_list;
  412. }
  413.  
  414. # if ((XmVersion > 1001) && defined(FEAT_XFONTSET)) || defined(PROTO)
  415.     XmFontList
  416. gui_motif_fontset2fontlist(fontset)
  417.     XFontSet    *fontset;
  418. {
  419.     XmFontList font_list;
  420.  
  421.     /* Motif 1.2 method */
  422.     XmFontListEntry font_list_entry;
  423.  
  424.     font_list_entry = XmFontListEntryCreate(STRING_TAG,
  425.                         XmFONT_IS_FONTSET,
  426.                         (XtPointer)*fontset);
  427.     font_list = XmFontListAppendEntry(NULL, font_list_entry);
  428.     XmFontListEntryFree(&font_list_entry);
  429.     return font_list;
  430. }
  431. # endif
  432.  
  433. #endif
  434.  
  435. #if defined(FEAT_MENU) || defined(PROTO)
  436. /*
  437.  * Menu stuff.
  438.  */
  439.  
  440. static void gui_motif_add_actext __ARGS((vimmenu_T *menu));
  441. #if (XmVersion >= 1002)
  442. static void toggle_tearoff __ARGS((Widget wid));
  443. static void gui_mch_recurse_tearoffs __ARGS((vimmenu_T *menu));
  444. #endif
  445. static void gui_mch_submenu_change __ARGS((vimmenu_T *mp, int colors));
  446.  
  447. static void do_set_mnemonics __ARGS((int enable));
  448. static int menu_enabled = TRUE;
  449.  
  450.     void
  451. gui_mch_enable_menu(flag)
  452.     int        flag;
  453. {
  454.     if (flag)
  455.     {
  456.     XtManageChild(menuBar);
  457. #ifdef FEAT_TOOLBAR
  458.     if (XtIsManaged(XtParent(toolBar)))
  459.     {
  460.         /* toolBar is attached to top form */
  461.         XtVaSetValues(XtParent(toolBar),
  462.         XmNtopAttachment, XmATTACH_WIDGET,
  463.         XmNtopWidget, menuBar,
  464.         NULL);
  465.         XtVaSetValues(textAreaForm,
  466.         XmNtopAttachment, XmATTACH_WIDGET,
  467.         XmNtopWidget, XtParent(toolBar),
  468.         NULL);
  469.     }
  470.     else
  471. #endif
  472.     {
  473.         XtVaSetValues(textAreaForm,
  474.         XmNtopAttachment, XmATTACH_WIDGET,
  475.         XmNtopWidget, menuBar,
  476.         NULL);
  477.     }
  478.     }
  479.     else
  480.     {
  481.     XtUnmanageChild(menuBar);
  482. #ifdef FEAT_TOOLBAR
  483.     if (XtIsManaged(XtParent(toolBar)))
  484.     {
  485.         XtVaSetValues(XtParent(toolBar),
  486.         XmNtopAttachment, XmATTACH_FORM,
  487.         NULL);
  488.         XtVaSetValues(textAreaForm,
  489.         XmNtopAttachment, XmATTACH_WIDGET,
  490.         XmNtopWidget, XtParent(toolBar),
  491.         NULL);
  492.     }
  493.     else
  494. #endif
  495.     {
  496.         XtVaSetValues(textAreaForm,
  497.         XmNtopAttachment, XmATTACH_FORM,
  498.         NULL);
  499.     }
  500.     }
  501.  
  502. }
  503.  
  504. /*
  505.  * Enable or disable mnemonics for the toplevel menus.
  506.  */
  507.     void
  508. gui_motif_set_mnemonics(enable)
  509.     int        enable;
  510. {
  511.     /*
  512.      * Don't enable menu mnemonics when the menu bar is disabled, LessTif
  513.      * crashes when using a mnemonic then.
  514.      */
  515.     if (!menu_enabled)
  516.     enable = FALSE;
  517.     do_set_mnemonics(enable);
  518. }
  519.  
  520.     static void
  521. do_set_mnemonics(enable)
  522.     int        enable;
  523. {
  524.     vimmenu_T    *menu;
  525.  
  526.     for (menu = root_menu; menu != NULL; menu = menu->next)
  527.     if (menu->id != (Widget)0)
  528.         XtVaSetValues(menu->id,
  529.             XmNmnemonic, enable ? menu->mnemonic : NUL,
  530.             NULL);
  531. }
  532.  
  533.     void
  534. gui_mch_add_menu(menu, idx)
  535.     vimmenu_T    *menu;
  536.     int        idx;
  537. {
  538.     XmString    label;
  539.     Widget    shell;
  540.     vimmenu_T    *parent = menu->parent;
  541.  
  542. #ifdef MOTIF_POPUP
  543.     if (menu_is_popup(menu->name))
  544.     {
  545.     Arg arg[2];
  546.     int n = 0;
  547.  
  548.     /* Only create the popup menu when it's actually used, otherwise there
  549.      * is a delay when using the right mouse button. */
  550. # if (XmVersion <= 1002)
  551.     if (mouse_model_popup())
  552. # endif
  553.     {
  554.         if (gui.menu_bg_pixel != INVALCOLOR)
  555.         {
  556.         XtSetArg(arg[0], XmNbackground, gui.menu_bg_pixel); n++;
  557.         }
  558.         if (gui.menu_fg_pixel != INVALCOLOR)
  559.         {
  560.         XtSetArg(arg[1], XmNforeground, gui.menu_fg_pixel); n++;
  561.         }
  562.         menu->submenu_id = XmCreatePopupMenu(textArea, "contextMenu",
  563.                                       arg, n);
  564.         menu->id = (Widget)0;
  565.     }
  566.     return;
  567.     }
  568. #endif
  569.  
  570.     if (!menu_is_menubar(menu->name)
  571.         || (parent != NULL && parent->submenu_id == (Widget)0))
  572.     return;
  573.  
  574.     label = XmStringCreate((char *)menu->dname, STRING_TAG);
  575.     if (label == NULL)
  576.     return;
  577.     menu->id = XtVaCreateWidget("subMenu",
  578.         xmCascadeButtonWidgetClass,
  579.         (parent == NULL) ? menuBar : parent->submenu_id,
  580.         XmNlabelString, label,
  581.         XmNmnemonic, p_wak[0] == 'n' ? NUL : menu->mnemonic,
  582. #if (XmVersion >= 1002)
  583.         /* submenu: count the tearoff item (needed for LessTif) */
  584.         XmNpositionIndex, idx + (parent != NULL
  585.                && tearoff_val == (int)XmTEAR_OFF_ENABLED ? 1 : 0),
  586. #endif
  587.         NULL);
  588.     gui_motif_menu_colors(menu->id);
  589.     gui_motif_menu_fontlist(menu->id);
  590.     XmStringFree(label);
  591.  
  592.     if (menu->id == (Widget)0)        /* failed */
  593.     return;
  594.  
  595.     /* add accelerator text */
  596.     gui_motif_add_actext(menu);
  597.  
  598.     shell = XtVaCreateWidget("subMenuShell",
  599.     xmMenuShellWidgetClass, menu->id,
  600.     XmNwidth, 1,
  601.     XmNheight, 1,
  602.     NULL);
  603.     gui_motif_menu_colors(shell);
  604.     menu->submenu_id = XtVaCreateWidget("rowColumnMenu",
  605.     xmRowColumnWidgetClass, shell,
  606.     XmNrowColumnType, XmMENU_PULLDOWN,
  607.     NULL);
  608.     gui_motif_menu_colors(menu->submenu_id);
  609.  
  610.     if (menu->submenu_id == (Widget)0)        /* failed */
  611.     return;
  612.  
  613. #if (XmVersion >= 1002)
  614.     /* Set the colors for the tear off widget */
  615.     toggle_tearoff(menu->submenu_id);
  616. #endif
  617.  
  618.     XtVaSetValues(menu->id,
  619.     XmNsubMenuId, menu->submenu_id,
  620.     NULL);
  621.  
  622.     /*
  623.      * The "Help" menu is a special case, and should be placed at the far
  624.      * right hand side of the menu-bar.  It's recognized by its high priority.
  625.      */
  626.     if (parent == NULL && menu->priority >= 9999)
  627.     XtVaSetValues(menuBar,
  628.         XmNmenuHelpWidget, menu->id,
  629.         NULL);
  630.  
  631.     /*
  632.      * When we add a top-level item to the menu bar, we can figure out how
  633.      * high the menu bar should be.
  634.      */
  635.     if (parent == NULL)
  636.     gui_mch_compute_menu_height(menu->id);
  637. }
  638.  
  639.  
  640. /*
  641.  * Add mnemonic and accelerator text to a menu button.
  642.  */
  643.     static void
  644. gui_motif_add_actext(menu)
  645.     vimmenu_T    *menu;
  646. {
  647.     XmString    label;
  648.  
  649.     /* Add accelrator text, if there is one */
  650.     if (menu->actext != NULL && menu->id != (Widget)0)
  651.     {
  652.     label = XmStringCreate((char *)menu->actext, STRING_TAG);
  653.     if (label == NULL)
  654.         return;
  655.     XtVaSetValues(menu->id, XmNacceleratorText, label, NULL);
  656.     XmStringFree(label);
  657.     }
  658. }
  659.  
  660.     void
  661. gui_mch_toggle_tearoffs(enable)
  662.     int        enable;
  663. {
  664. #if (XmVersion >= 1002)
  665.     if (enable)
  666.     tearoff_val = (int)XmTEAR_OFF_ENABLED;
  667.     else
  668.     tearoff_val = (int)XmTEAR_OFF_DISABLED;
  669.     toggle_tearoff(menuBar);
  670.     gui_mch_recurse_tearoffs(root_menu);
  671. #endif
  672. }
  673.  
  674. #if (XmVersion >= 1002)
  675. /*
  676.  * Set the tearoff for one menu widget on or off, and set the color of the
  677.  * tearoff widget.
  678.  */
  679.     static void
  680. toggle_tearoff(wid)
  681.     Widget    wid;
  682. {
  683.     Widget    w;
  684.  
  685.     XtVaSetValues(wid, XmNtearOffModel, tearoff_val, NULL);
  686.     if (tearoff_val == (int)XmTEAR_OFF_ENABLED
  687.         && (w = XmGetTearOffControl(wid)) != (Widget)0)
  688.     gui_motif_menu_colors(w);
  689. }
  690.  
  691.     static void
  692. gui_mch_recurse_tearoffs(menu)
  693.     vimmenu_T    *menu;
  694. {
  695.     while (menu != NULL)
  696.     {
  697.     if (!menu_is_popup(menu->name))
  698.     {
  699.         if (menu->submenu_id != (Widget)0)
  700.         toggle_tearoff(menu->submenu_id);
  701.         gui_mch_recurse_tearoffs(menu->children);
  702.     }
  703.     menu = menu->next;
  704.     }
  705. }
  706. #endif
  707.  
  708.     int
  709. gui_mch_text_area_extra_height()
  710. {
  711.     Dimension    shadowHeight;
  712.  
  713.     XtVaGetValues(textAreaForm, XmNshadowThickness, &shadowHeight, NULL);
  714.     return shadowHeight;
  715. }
  716.  
  717. /*
  718.  * Compute the height of the menu bar.
  719.  * We need to check all the items for their position and height, for the case
  720.  * there are several rows, and/or some characters extend higher or lower.
  721.  */
  722.     void
  723. gui_mch_compute_menu_height(id)
  724.     Widget    id;            /* can be NULL when deleting menu */
  725. {
  726.     Dimension    y, maxy;
  727.     Dimension    margin, shadow;
  728.     vimmenu_T    *mp;
  729.     static Dimension    height = 21;    /* normal height of a menu item */
  730.  
  731.     /*
  732.      * Get the height of the new item, before managing it, because it will
  733.      * still reflect the font size.  After managing it depends on the menu
  734.      * height, which is what we just wanted to get!.
  735.      */
  736.     if (id != (Widget)0)
  737.     XtVaGetValues(id, XmNheight, &height, NULL);
  738.  
  739.     /* Find any menu Widget, to be able to call XtManageChild() */
  740.     else
  741.     for (mp = root_menu; mp != NULL; mp = mp->next)
  742.         if (mp->id != (Widget)0 && menu_is_menubar(mp->name))
  743.         {
  744.         id = mp->id;
  745.         break;
  746.         }
  747.  
  748.     /*
  749.      * Now manage the menu item, to make them all be positioned (makes an
  750.      * extra row when needed, removes it when not needed).
  751.      */
  752.     if (id != (Widget)0)
  753.     XtManageChild(id);
  754.  
  755.     /*
  756.      * Now find the menu item that is the furthest down, and get it's position.
  757.      */
  758.     maxy = 0;
  759.     for (mp = root_menu; mp != NULL; mp = mp->next)
  760.     {
  761.     if (mp->id != (Widget)0 && menu_is_menubar(mp->name))
  762.     {
  763.         XtVaGetValues(mp->id, XmNy, &y, NULL);
  764.         if (y > maxy)
  765.         maxy = y;
  766.     }
  767.     }
  768.  
  769.     XtVaGetValues(menuBar,
  770.     XmNmarginHeight, &margin,
  771.     XmNshadowThickness, &shadow,
  772.     NULL);
  773.  
  774.     /*
  775.      * This computation is the result of trial-and-error:
  776.      * maxy =    The maximum position of an item; required for when there are
  777.      *        two or more rows
  778.      * height = height of an item, before managing it;    Hopefully this will
  779.      *        change with the font height.  Includes shadow-border.
  780.      * shadow =    shadow-border; must be subtracted from the height.
  781.      * margin = margin around the menu buttons;  Must be added.
  782.      * Add 4 for the underlining of shortcut keys.
  783.      */
  784.     gui.menu_height = maxy + height - 2 * shadow + 2 * margin + 4;
  785.  
  786. #ifdef LESSTIF_VERSION
  787.     /* Somehow the menu bar doesn't resize automatically.  Set it here,
  788.      * even though this is a catch 22.  Don't do this when starting up,
  789.      * somehow the menu gets very high then. */
  790.     if (gui.shell_created)
  791.     XtVaSetValues(menuBar, XmNheight, gui.menu_height, NULL);
  792. #endif
  793. }
  794.  
  795.     void
  796. gui_mch_add_menu_item(menu, idx)
  797.     vimmenu_T    *menu;
  798.     int        idx;
  799. {
  800.     XmString    label;
  801.     vimmenu_T    *parent = menu->parent;
  802.  
  803. # ifdef EBCDIC
  804.     menu->mnemonic = 0;
  805. # endif
  806.  
  807. # if (XmVersion <= 1002)
  808.     /* Don't add Popup menu items when the popup menu isn't used. */
  809.     if (menu_is_child_of_popup(menu) && !mouse_model_popup())
  810.     return;
  811. # endif
  812.  
  813. # ifdef FEAT_TOOLBAR
  814.     if (menu_is_toolbar(parent->name))
  815.     {
  816.     WidgetClass    type;
  817.     XmString    xms = NULL;    /* fallback label if pixmap not found */
  818.     int        n;
  819.     Arg        args[18];
  820.  
  821.     n = 0;
  822.     if (menu_is_separator(menu->name))
  823.     {
  824.         char    *cp;
  825.         Dimension    wid;
  826.  
  827.         /*
  828.          * A separator has the format "-sep%d[:%d]-". The optional :%d is
  829.          * a width specifier. If no width is specified then we choose one.
  830.          */
  831.         cp = (char *)vim_strchr(menu->name, ':');
  832.         if (cp != NULL)
  833.         wid = (Dimension)atoi(++cp);
  834.         else
  835.         wid = 4;
  836.  
  837. #if 0
  838.         /* We better use a FormWidget here, since it's far more
  839.          * flexible in terms of size.  */
  840.         type = xmFormWidgetClass;
  841.         XtSetArg(args[n], XmNwidth, wid); n++;
  842. #else
  843.         type = xmSeparatorWidgetClass;
  844.         XtSetArg(args[n], XmNwidth, wid); n++;
  845.         XtSetArg(args[n], XmNminWidth, wid); n++;
  846.         XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  847.         XtSetArg(args[n], XmNseparatorType, XmNO_LINE); n++;
  848. #endif
  849.     }
  850.     else
  851.     {
  852.         get_toolbar_pixmap(menu, &menu->image, &menu->image_ins);
  853.         /* Set the label here, so that we can switch between icons/text
  854.          * by changing the XmNlabelType resource. */
  855.         xms = XmStringCreate((char *)menu->dname, STRING_TAG);
  856.         XtSetArg(args[n], XmNlabelString, xms); n++;
  857.  
  858. #ifndef FEAT_SUN_WORKSHOP
  859.  
  860.         /* Without shadows one can't sense whatever the button has been
  861.          * pressed or not! However we wan't to save a bit of space...
  862.          */
  863.         XtSetArg(args[n], XmNhighlightThickness, 0); n++;
  864.         XtSetArg(args[n], XmNhighlightOnEnter, True); n++;
  865.         XtSetArg(args[n], XmNmarginWidth, 0); n++;
  866.         XtSetArg(args[n], XmNmarginHeight, 0); n++;
  867. #endif
  868.         if (menu->image == 0)
  869.         {
  870.         XtSetArg(args[n], XmNlabelType, XmSTRING); n++;
  871.         XtSetArg(args[n], XmNlabelPixmap, 0); n++;
  872.         XtSetArg(args[n], XmNlabelInsensitivePixmap, 0); n++;
  873.         }
  874.         else
  875.         {
  876.         XtSetArg(args[n], XmNlabelPixmap, menu->image); n++;
  877.         XtSetArg(args[n], XmNlabelInsensitivePixmap, menu->image_ins); n++;
  878.         XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++;
  879.         }
  880.         type = xmPushButtonWidgetClass;
  881.         XtSetArg(args[n], XmNwidth, 80); n++;
  882.     }
  883.  
  884.     XtSetArg(args[n], XmNpositionIndex, idx); n++;
  885.     if (menu->id == NULL)
  886.     {
  887.         menu->id = XtCreateManagedWidget((char *)menu->dname,
  888.             type, toolBar, args, n);
  889.         if (menu->id != NULL && type == xmPushButtonWidgetClass)
  890.         {
  891.         XtAddCallback(menu->id,
  892.             XmNactivateCallback, gui_x11_menu_cb, menu);
  893.  
  894. # ifdef FEAT_FOOTER
  895.         XtAddEventHandler(menu->id, EnterWindowMask, False,
  896.             toolbarbutton_enter_cb, menu);
  897.         XtAddEventHandler(menu->id, LeaveWindowMask, False,
  898.             toolbarbutton_leave_cb, menu);
  899. # endif
  900.         }
  901.     }
  902.     else
  903.         XtSetValues(menu->id, args, n);
  904.     if (xms != NULL)
  905.         XmStringFree(xms);
  906.  
  907. #ifdef FEAT_BEVAL
  908.     gui_mch_menu_set_tip(menu);
  909. #endif
  910.  
  911.     menu->parent = parent;
  912.     menu->submenu_id = NULL;
  913.     /* When adding first item to toolbar it might have to be enabled .*/
  914.     if (!XtIsManaged(XtParent(toolBar))
  915.             && vim_strchr(p_go, GO_TOOLBAR) != NULL)
  916.         gui_mch_show_toolbar(TRUE);
  917.     gui.toolbar_height = gui_mch_compute_toolbar_height();
  918.     return;
  919.     } /* toolbar menu item */
  920. # endif
  921.  
  922.     /* No parent, must be a non-menubar menu */
  923.     if (parent->submenu_id == (Widget)0)
  924.     return;
  925.  
  926.     menu->submenu_id = (Widget)0;
  927.  
  928.     /* Add menu separator */
  929.     if (menu_is_separator(menu->name))
  930.     {
  931.     menu->id = XtVaCreateWidget("subMenu",
  932.         xmSeparatorGadgetClass, parent->submenu_id,
  933. #if (XmVersion >= 1002)
  934.         /* count the tearoff item (needed for LessTif) */
  935.         XmNpositionIndex, idx + (tearoff_val == (int)XmTEAR_OFF_ENABLED
  936.                                      ? 1 : 0),
  937. #endif
  938.         NULL);
  939.     gui_motif_menu_colors(menu->id);
  940.     return;
  941.     }
  942.  
  943.     label = XmStringCreate((char *)menu->dname, STRING_TAG);
  944.     if (label == NULL)
  945.     return;
  946.     menu->id = XtVaCreateWidget("subMenu",
  947.     xmPushButtonWidgetClass, parent->submenu_id,
  948.     XmNlabelString, label,
  949.     XmNmnemonic, menu->mnemonic,
  950. #if (XmVersion >= 1002)
  951.     /* count the tearoff item (needed for LessTif) */
  952.     XmNpositionIndex, idx + (tearoff_val == (int)XmTEAR_OFF_ENABLED
  953.                                      ? 1 : 0),
  954. #endif
  955.     NULL);
  956.     gui_motif_menu_colors(menu->id);
  957.     gui_motif_menu_fontlist(menu->id);
  958.     XmStringFree(label);
  959.  
  960.     if (menu->id != (Widget)0)
  961.     {
  962.     XtAddCallback(menu->id, XmNactivateCallback, gui_x11_menu_cb,
  963.         (XtPointer)menu);
  964.     /* add accelerator text */
  965.     gui_motif_add_actext(menu);
  966.     }
  967. }
  968.  
  969. #if (XmVersion <= 1002) || defined(PROTO)
  970. /*
  971.  * This function will destroy/create the popup menus dynamically,
  972.  * according to the value of 'mousemodel'.
  973.  * This will fix the "right mouse button freeze" that occurs when
  974.  * there exists a popup menu but it isn't managed.
  975.  */
  976.     void
  977. gui_motif_update_mousemodel(menu)
  978.     vimmenu_T    *menu;
  979. {
  980.     int        idx = 0;
  981.  
  982.     /* When GUI hasn't started the menus have not been created. */
  983.     if (!gui.in_use)
  984.       return;
  985.  
  986.     while (menu)
  987.     {
  988.       if (menu->children != NULL)
  989.       {
  990.       if (menu_is_popup(menu->name))
  991.       {
  992.           if (mouse_model_popup())
  993.           {
  994.           /* Popup menu will be used.  Create the popup menus. */
  995.           gui_mch_add_menu(menu, idx);
  996.           gui_motif_update_mousemodel(menu->children);
  997.           }
  998.           else
  999.           {
  1000.           /* Popup menu will not be used.  Destroy the popup menus. */
  1001.           gui_motif_update_mousemodel(menu->children);
  1002.           gui_mch_destroy_menu(menu);
  1003.           }
  1004.       }
  1005.       }
  1006.       else if (menu_is_child_of_popup(menu))
  1007.       {
  1008.       if (mouse_model_popup())
  1009.           gui_mch_add_menu_item(menu, idx);
  1010.       else
  1011.           gui_mch_destroy_menu(menu);
  1012.       }
  1013.       menu = menu->next;
  1014.       ++idx;
  1015.     }
  1016. }
  1017. #endif
  1018.  
  1019.     void
  1020. gui_mch_new_menu_colors()
  1021. {
  1022.     if (menuBar == (Widget)0)
  1023.     return;
  1024.     gui_motif_menu_colors(menuBar);
  1025. #ifdef FEAT_TOOLBAR
  1026.     gui_motif_menu_colors(toolBarFrame);
  1027.     gui_motif_menu_colors(toolBar);
  1028. #endif
  1029.  
  1030.     gui_mch_submenu_change(root_menu, TRUE);
  1031. }
  1032.  
  1033.     void
  1034. gui_mch_new_menu_font()
  1035. {
  1036.     if (menuBar == (Widget)0)
  1037.     return;
  1038.     gui_mch_submenu_change(root_menu, FALSE);
  1039.     {
  1040.     Dimension   height;
  1041.     Position w, h;
  1042.  
  1043.     XtVaGetValues(menuBar, XmNheight, &height, NULL);
  1044.     gui.menu_height = height;
  1045.  
  1046.     XtVaGetValues(vimShell, XtNwidth, &w, XtNheight, &h, NULL);
  1047.     gui_resize_shell(w, h
  1048. #ifdef FEAT_XIM
  1049.         - xim_get_status_area_height()
  1050. #endif
  1051.              );
  1052.     }
  1053.     gui_set_shellsize(FALSE, TRUE);
  1054.     ui_new_shellsize();
  1055. }
  1056.  
  1057. #if defined(FEAT_BEVAL) || defined(PROTO)
  1058.     void
  1059. gui_mch_new_tooltip_font()
  1060. {
  1061. # ifdef FEAT_TOOLBAR
  1062.     vimmenu_T   *menu;
  1063.  
  1064.     if (toolBar == (Widget)0)
  1065.     return;
  1066.  
  1067.     menu = gui_find_menu((char_u *)"ToolBar");
  1068.     if (menu != NULL)
  1069.     gui_mch_submenu_change(menu, FALSE);
  1070. # endif
  1071. }
  1072.  
  1073.     void
  1074. gui_mch_new_tooltip_colors()
  1075. {
  1076. # ifdef FEAT_TOOLBAR
  1077.     vimmenu_T   *toolbar;
  1078.  
  1079.     if (toolBar == (Widget)0)
  1080.     return;
  1081.  
  1082.     toolbar = gui_find_menu((char_u *)"ToolBar");
  1083.     if (toolbar != NULL)
  1084.     gui_mch_submenu_change(toolbar, TRUE);
  1085. # endif
  1086. }
  1087. #endif
  1088.  
  1089.     static void
  1090. gui_mch_submenu_change(menu, colors)
  1091.     vimmenu_T    *menu;
  1092.     int        colors;        /* TRUE for colors, FALSE for font */
  1093. {
  1094.     vimmenu_T    *mp;
  1095.  
  1096.     for (mp = menu; mp != NULL; mp = mp->next)
  1097.     {
  1098.     if (mp->id != (Widget)0)
  1099.     {
  1100.         if (colors)
  1101.         {
  1102.         gui_motif_menu_colors(mp->id);
  1103. #ifdef FEAT_TOOLBAR
  1104.         /* For a toolbar item: Free the pixmap and allocate a new one,
  1105.          * so that the background color is right. */
  1106.         if (mp->image != (Pixmap)0)
  1107.         {
  1108.             XFreePixmap(gui.dpy, mp->image);
  1109.             XFreePixmap(gui.dpy, mp->image_ins);
  1110.             get_toolbar_pixmap(mp, &mp->image, &mp->image_ins);
  1111.             if (mp->image != (Pixmap)0)
  1112.             XtVaSetValues(mp->id,
  1113.                 XmNlabelPixmap, mp->image,
  1114.                 XmNlabelInsensitivePixmap, mp->image_ins,
  1115.                 NULL);
  1116.         }
  1117. # ifdef FEAT_BEVAL
  1118.         /* If we have a tooltip, then we need to change it's font */
  1119.         if (mp->tip != NULL)
  1120.         {
  1121.             Arg args[2];
  1122.  
  1123.             args[0].name = XmNbackground;
  1124.             args[0].value = gui.tooltip_bg_pixel;
  1125.             args[1].name = XmNforeground;
  1126.             args[1].value = gui.tooltip_fg_pixel;
  1127.             XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args));
  1128.         }
  1129. # endif
  1130. #endif
  1131.         }
  1132.         else
  1133.         {
  1134.         gui_motif_menu_fontlist(mp->id);
  1135. #ifdef FEAT_BEVAL
  1136.         /* If we have a tooltip, then we need to change it's font */
  1137.         if (mp->tip != NULL)
  1138.         {
  1139.             Arg args[1];
  1140.  
  1141.             args[0].name = XmNfontList;
  1142.             args[0].value = (XtArgVal)gui_motif_fontset2fontlist(
  1143.                             &gui.tooltip_fontset);
  1144.             XtSetValues(mp->tip->balloonLabel, &args[0], XtNumber(args));
  1145.         }
  1146. #endif
  1147.         }
  1148.     }
  1149.  
  1150.     if (mp->children != NULL)
  1151.     {
  1152. #if (XmVersion >= 1002)
  1153.         /* Set the colors/font for the tear off widget */
  1154.         if (mp->submenu_id != (Widget)0)
  1155.         {
  1156.         if (colors)
  1157.             gui_motif_menu_colors(mp->submenu_id);
  1158.         else
  1159.             gui_motif_menu_fontlist(mp->submenu_id);
  1160.         toggle_tearoff(mp->submenu_id);
  1161.         }
  1162. #endif
  1163.         /* Set the colors for the children */
  1164.         gui_mch_submenu_change(mp->children, colors);
  1165.     }
  1166.     }
  1167. }
  1168.  
  1169. /*
  1170.  * Destroy the machine specific menu widget.
  1171.  */
  1172.     void
  1173. gui_mch_destroy_menu(menu)
  1174.     vimmenu_T    *menu;
  1175. {
  1176.     /* Please be sure to destroy the parent widget first (i.e. menu->id).
  1177.      * On the other hand, problems have been reported that the submenu must be
  1178.      * deleted first...
  1179.      *
  1180.      * This code should be basically identical to that in the file gui_athena.c
  1181.      * because they are both Xt based.
  1182.      */
  1183.     if (menu->submenu_id != (Widget)0)
  1184.     {
  1185.     XtDestroyWidget(menu->submenu_id);
  1186.     menu->submenu_id = (Widget)0;
  1187.     }
  1188.  
  1189.     if (menu->id != (Widget)0)
  1190.     {
  1191.     Widget        parent;
  1192.  
  1193.     parent = XtParent(menu->id);
  1194. #if defined(FEAT_TOOLBAR) && defined(FEAT_BEVAL)
  1195.     if ((parent == toolBar) && (menu->tip != NULL))
  1196.     {
  1197.         /* We try to destroy this before the actual menu, because there are
  1198.          * callbacks, etc. that will be unregistered during the tooltip
  1199.          * destruction.
  1200.          *
  1201.          * If you call "gui_mch_destroy_beval_area()" after destroying
  1202.          * menu->id, then the tooltip's window will have already been
  1203.          * deallocated by Xt, and unknown behaviour will ensue (probably
  1204.          * a core dump).
  1205.          */
  1206.         gui_mch_destroy_beval_area(menu->tip);
  1207.         menu->tip = NULL;
  1208.     }
  1209. #endif
  1210.     XtDestroyWidget(menu->id);
  1211.     menu->id = (Widget)0;
  1212.     if (parent == menuBar)
  1213.         gui_mch_compute_menu_height((Widget)0);
  1214. #ifdef FEAT_TOOLBAR
  1215.     else if (parent == toolBar)
  1216.     {
  1217.         Cardinal    num_children;
  1218.  
  1219.         /* When removing last toolbar item, don't display the toolbar. */
  1220.         XtVaGetValues(toolBar, XmNnumChildren, &num_children, NULL);
  1221.         if (num_children == 0)
  1222.         gui_mch_show_toolbar(FALSE);
  1223.         else
  1224.         gui.toolbar_height = gui_mch_compute_toolbar_height();
  1225.     }
  1226. #endif
  1227.     }
  1228. }
  1229.  
  1230. /* ARGSUSED */
  1231.     void
  1232. gui_mch_show_popupmenu(menu)
  1233.     vimmenu_T *menu;
  1234. {
  1235. #ifdef MOTIF_POPUP
  1236.     XmMenuPosition(menu->submenu_id, gui_x11_get_last_mouse_event());
  1237.     XtManageChild(menu->submenu_id);
  1238. #endif
  1239. }
  1240.  
  1241. #endif /* FEAT_MENU */
  1242.  
  1243. /*
  1244.  * Set the menu and scrollbar colors to their default values.
  1245.  */
  1246.     void
  1247. gui_mch_def_colors()
  1248. {
  1249.     if (gui.in_use)
  1250.     {
  1251.     /* Use the values saved when starting up.  These should come from the
  1252.      * window manager or a resources file. */
  1253.     gui.menu_fg_pixel = gui.menu_def_fg_pixel;
  1254.     gui.menu_bg_pixel = gui.menu_def_bg_pixel;
  1255.     gui.scroll_fg_pixel = gui.scroll_def_fg_pixel;
  1256.     gui.scroll_bg_pixel = gui.scroll_def_bg_pixel;
  1257. #ifdef FEAT_BEVAL
  1258.     gui.tooltip_fg_pixel =
  1259.             gui_get_color((char_u *)gui.rsrc_tooltip_fg_name);
  1260.     gui.tooltip_bg_pixel =
  1261.             gui_get_color((char_u *)gui.rsrc_tooltip_bg_name);
  1262. #endif
  1263.     }
  1264. }
  1265.  
  1266.  
  1267. /*
  1268.  * Scrollbar stuff.
  1269.  */
  1270.  
  1271.     void
  1272. gui_mch_set_scrollbar_thumb(sb, val, size, max)
  1273.     scrollbar_T *sb;
  1274.     long    val;
  1275.     long    size;
  1276.     long    max;
  1277. {
  1278.     if (sb->id != (Widget)0)
  1279.     XtVaSetValues(sb->id,
  1280.           XmNvalue, val,
  1281.           XmNsliderSize, size,
  1282.           XmNpageIncrement, (size > 2 ? size - 2 : 1),
  1283.           XmNmaximum, max + 1,        /* Motif has max one past the end */
  1284.           NULL);
  1285. }
  1286.  
  1287.     void
  1288. gui_mch_set_scrollbar_pos(sb, x, y, w, h)
  1289.     scrollbar_T *sb;
  1290.     int        x;
  1291.     int        y;
  1292.     int        w;
  1293.     int        h;
  1294. {
  1295.     if (sb->id != (Widget)0)
  1296.     {
  1297.     if (sb->type == SBAR_LEFT || sb->type == SBAR_RIGHT)
  1298.     {
  1299.         if (y == 0)
  1300.         h -= gui.border_offset;
  1301.         else
  1302.         y -= gui.border_offset;
  1303.         XtVaSetValues(sb->id,
  1304.               XmNtopOffset, y,
  1305.               XmNbottomOffset, -y - h,
  1306.               XmNwidth, w,
  1307.               NULL);
  1308.     }
  1309.     else
  1310.         XtVaSetValues(sb->id,
  1311.               XmNtopOffset, y,
  1312.               XmNleftOffset, x,
  1313.               XmNrightOffset, gui.which_scrollbars[SBAR_RIGHT]
  1314.                             ? gui.scrollbar_width : 0,
  1315.               XmNheight, h,
  1316.               NULL);
  1317.     XtManageChild(sb->id);
  1318.     }
  1319. }
  1320.  
  1321.     void
  1322. gui_mch_enable_scrollbar(sb, flag)
  1323.     scrollbar_T *sb;
  1324.     int        flag;
  1325. {
  1326.     Arg        args[16];
  1327.     int        n;
  1328.  
  1329.     if (sb->id != (Widget)0)
  1330.     {
  1331.     n = 0;
  1332.     if (flag)
  1333.     {
  1334.         switch (sb->type)
  1335.         {
  1336.         case SBAR_LEFT:
  1337.             XtSetArg(args[n], XmNleftOffset, gui.scrollbar_width); n++;
  1338.             break;
  1339.  
  1340.         case SBAR_RIGHT:
  1341.             XtSetArg(args[n], XmNrightOffset, gui.scrollbar_width); n++;
  1342.             break;
  1343.  
  1344.         case SBAR_BOTTOM:
  1345.             XtSetArg(args[n], XmNbottomOffset, gui.scrollbar_height);n++;
  1346.             break;
  1347.         }
  1348.         XtSetValues(textArea, args, n);
  1349.         XtManageChild(sb->id);
  1350.     }
  1351.     else
  1352.     {
  1353.         if (!gui.which_scrollbars[sb->type])
  1354.         {
  1355.         /* The scrollbars of this type are all disabled, adjust the
  1356.          * textArea attachment offset. */
  1357.         switch (sb->type)
  1358.         {
  1359.             case SBAR_LEFT:
  1360.             XtSetArg(args[n], XmNleftOffset, 0); n++;
  1361.             break;
  1362.  
  1363.             case SBAR_RIGHT:
  1364.             XtSetArg(args[n], XmNrightOffset, 0); n++;
  1365.             break;
  1366.  
  1367.             case SBAR_BOTTOM:
  1368.             XtSetArg(args[n], XmNbottomOffset, 0);n++;
  1369.             break;
  1370.         }
  1371.         XtSetValues(textArea, args, n);
  1372.         }
  1373.         XtUnmanageChild(sb->id);
  1374.     }
  1375.     }
  1376. }
  1377.  
  1378.     void
  1379. gui_mch_create_scrollbar(sb, orient)
  1380.     scrollbar_T *sb;
  1381.     int        orient;    /* SBAR_VERT or SBAR_HORIZ */
  1382. {
  1383.     Arg        args[16];
  1384.     int        n;
  1385.  
  1386.     n = 0;
  1387.     XtSetArg(args[n], XmNshadowThickness, 1); n++;
  1388.     XtSetArg(args[n], XmNminimum, 0); n++;
  1389.     XtSetArg(args[n], XmNorientation,
  1390.         (orient == SBAR_VERT) ? XmVERTICAL : XmHORIZONTAL); n++;
  1391.  
  1392.     switch (sb->type)
  1393.     {
  1394.     case SBAR_LEFT:
  1395.         XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1396.         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_FORM); n++;
  1397.         XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1398.         break;
  1399.  
  1400.     case SBAR_RIGHT:
  1401.         XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  1402.         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_FORM); n++;
  1403.         XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1404.         break;
  1405.  
  1406.     case SBAR_BOTTOM:
  1407.         XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  1408.         XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  1409.         XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  1410.         break;
  1411.     }
  1412.  
  1413.     sb->id = XtCreateWidget("scrollBar",
  1414.         xmScrollBarWidgetClass, textAreaForm, args, n);
  1415.  
  1416.     /* Remember the default colors, needed for ":hi clear". */
  1417.     if (gui.scroll_def_bg_pixel == (guicolor_T)0
  1418.         && gui.scroll_def_fg_pixel == (guicolor_T)0)
  1419.     XtVaGetValues(sb->id,
  1420.         XmNbackground, &gui.scroll_def_bg_pixel,
  1421.         XmNforeground, &gui.scroll_def_fg_pixel,
  1422.         NULL);
  1423.  
  1424.     if (sb->id != (Widget)0)
  1425.     {
  1426.     gui_mch_set_scrollbar_colors(sb);
  1427.     XtAddCallback(sb->id, XmNvalueChangedCallback,
  1428.               scroll_cb, (XtPointer)sb->ident);
  1429.     XtAddCallback(sb->id, XmNdragCallback,
  1430.               scroll_cb, (XtPointer)sb->ident);
  1431.     XtAddEventHandler(sb->id, KeyPressMask, FALSE, gui_x11_key_hit_cb,
  1432.         (XtPointer)0);
  1433.     }
  1434. }
  1435.  
  1436. #if defined(FEAT_WINDOWS) || defined(PROTO)
  1437.     void
  1438. gui_mch_destroy_scrollbar(sb)
  1439.     scrollbar_T *sb;
  1440. {
  1441.     if (sb->id != (Widget)0)
  1442.     XtDestroyWidget(sb->id);
  1443. }
  1444. #endif
  1445.  
  1446.     void
  1447. gui_mch_set_scrollbar_colors(sb)
  1448.     scrollbar_T *sb;
  1449. {
  1450.     if (sb->id != (Widget)0)
  1451.     {
  1452.     if (gui.scroll_bg_pixel != INVALCOLOR)
  1453.     {
  1454. #if (XmVersion>=1002)
  1455.         XmChangeColor(sb->id, gui.scroll_bg_pixel);
  1456. #else
  1457.         XtVaSetValues(sb->id,
  1458.             XmNtroughColor, gui.scroll_bg_pixel,
  1459.             NULL);
  1460. #endif
  1461.     }
  1462.  
  1463.     if (gui.scroll_fg_pixel != INVALCOLOR)
  1464.         XtVaSetValues(sb->id,
  1465.             XmNforeground, gui.scroll_fg_pixel,
  1466. #if (XmVersion<1002)
  1467.             XmNbackground, gui.scroll_fg_pixel,
  1468. #endif
  1469.             NULL);
  1470.     }
  1471.  
  1472.     /* This is needed for the rectangle below the vertical scrollbars. */
  1473.     if (sb == &gui.bottom_sbar && textAreaForm != (Widget)0)
  1474.     gui_motif_scroll_colors(textAreaForm);
  1475. }
  1476.  
  1477. /*
  1478.  * Miscellaneous stuff:
  1479.  */
  1480.  
  1481.     Window
  1482. gui_x11_get_wid()
  1483. {
  1484.     return(XtWindow(textArea));
  1485. }
  1486.  
  1487.  
  1488. #if defined(FEAT_BROWSE) || defined(PROTO)
  1489.  
  1490. /*
  1491.  * file selector related stuff
  1492.  */
  1493.  
  1494. #include <Xm/FileSB.h>
  1495. #include <Xm/XmStrDefs.h>
  1496.  
  1497. typedef struct dialog_callback_arg
  1498. {
  1499.     char *  args;   /* not used right now */
  1500.     int        id;
  1501. } dcbarg_T;
  1502.  
  1503. static Widget dialog_wgt;
  1504. static char *browse_fname = NULL;
  1505. static XmStringCharSet charset = (XmStringCharSet) XmSTRING_DEFAULT_CHARSET;
  1506.                 /* used to set up XmStrings */
  1507.  
  1508. static void DialogCancelCB __ARGS((Widget, XtPointer, XtPointer));
  1509. static void DialogAcceptCB __ARGS((Widget, XtPointer, XtPointer));
  1510.  
  1511. /*
  1512.  * This function is used to translate the predefined label text of the
  1513.  * precomposed dialogs. We do this explicitly to allow:
  1514.  *
  1515.  * - usage of gettext for translation, as in all the other places.
  1516.  *
  1517.  * - equalize the messages between different GUI implementations as far as
  1518.  * possible.
  1519.  */
  1520. static void set_predefined_label __ARGS((Widget parent, String name, char * new_label));
  1521.  
  1522. static void
  1523. set_predefined_label(parent, name, new_label)
  1524.     Widget parent;
  1525.     String name;
  1526.     char * new_label;
  1527. {
  1528.     XmString str;
  1529.     Widget w;
  1530.  
  1531.     w = XtNameToWidget(parent, name);
  1532.  
  1533.     if (!w)
  1534.     return;
  1535.  
  1536.     str = XmStringCreate(new_label, STRING_TAG);
  1537.  
  1538.     if (str)
  1539.     {
  1540.     XtVaSetValues(w, XmNlabelString, str, NULL);
  1541.     XmStringFree(str);
  1542.     }
  1543. }
  1544.  
  1545. /*
  1546.  * Put up a file requester.
  1547.  * Returns the selected name in allocated memory, or NULL for Cancel.
  1548.  */
  1549. /* ARGSUSED */
  1550.     char_u *
  1551. gui_mch_browse(saving, title, dflt, ext, initdir, filter)
  1552.     int        saving;        /* select file to write */
  1553.     char_u    *title;        /* title for the window */
  1554.     char_u    *dflt;        /* default name */
  1555.     char_u    *ext;        /* not used (extension added) */
  1556.     char_u    *initdir;    /* initial directory, NULL for current dir */
  1557.     char_u    *filter;    /* file name filter */
  1558. {
  1559.     char_u    dirbuf[MAXPATHL];
  1560.     char_u    dfltbuf[MAXPATHL];
  1561.     char_u    *pattern;
  1562.     char_u    *tofree = NULL;
  1563.  
  1564.     dialog_wgt = XmCreateFileSelectionDialog(vimShell, (char *)title, NULL, 0);
  1565.  
  1566.     if (initdir == NULL || *initdir == NUL)
  1567.     {
  1568.     mch_dirname(dirbuf, MAXPATHL);
  1569.     initdir = dirbuf;
  1570.     }
  1571.  
  1572.     if (dflt == NULL)
  1573.     dflt = (char_u *)"";
  1574.     else if (STRLEN(initdir) + STRLEN(dflt) + 2 < MAXPATHL)
  1575.     {
  1576.     /* The default selection should be the full path, "dflt" is only the
  1577.      * file name. */
  1578.     STRCPY(dfltbuf, initdir);
  1579.     add_pathsep(dfltbuf);
  1580.     STRCAT(dfltbuf, dflt);
  1581.     dflt = dfltbuf;
  1582.     }
  1583.  
  1584.     /* Can only use one pattern for a file name.  Get the first pattern out of
  1585.      * the filter.  An empty pattern means everything matches. */
  1586.     if (filter == NULL)
  1587.     pattern = (char_u *)"";
  1588.     else
  1589.     {
  1590.     char_u    *s, *p;
  1591.  
  1592.     s = filter;
  1593.     for (p = filter; *p != NUL; ++p)
  1594.     {
  1595.         if (*p == '\t')    /* end of description, start of pattern */
  1596.         s = p + 1;
  1597.         if (*p == ';' || *p == '\n')    /* end of (first) pattern */
  1598.         break;
  1599.     }
  1600.     pattern = vim_strnsave(s, p - s);
  1601.     tofree = pattern;
  1602.     if (pattern == NULL)
  1603.         pattern = (char_u *)"";
  1604.     }
  1605.  
  1606.     XtVaSetValues(dialog_wgt,
  1607.     XtVaTypedArg,
  1608.         XmNdirectory, XmRString, (char *)initdir, STRLEN(initdir) + 1,
  1609.     XtVaTypedArg,
  1610.         XmNdirSpec,    XmRString, (char *)dflt, STRLEN(dflt) + 1,
  1611.     XtVaTypedArg,
  1612.         XmNpattern,    XmRString, (char *)pattern, STRLEN(pattern) + 1,
  1613.     XtVaTypedArg,
  1614.         XmNdialogTitle, XmRString, (char *)title, STRLEN(title) + 1,
  1615.     NULL);
  1616.  
  1617.     set_predefined_label(dialog_wgt, "Apply", _("Filter"));
  1618.     set_predefined_label(dialog_wgt, "Cancel", _("Cancel"));
  1619.     set_predefined_label(dialog_wgt, "Dir", _("Directories"));
  1620.     set_predefined_label(dialog_wgt, "FilterLabel", _("Filter"));
  1621.     set_predefined_label(dialog_wgt, "Help", _("Help"));
  1622.     set_predefined_label(dialog_wgt, "Items", _("Files"));
  1623.     set_predefined_label(dialog_wgt, "OK", _("OK"));
  1624.     set_predefined_label(dialog_wgt, "Selection", _("Selection"));
  1625.  
  1626.     gui_motif_menu_colors(dialog_wgt);
  1627.     if (gui.scroll_bg_pixel != INVALCOLOR)
  1628.     XtVaSetValues(dialog_wgt, XmNtroughColor, gui.scroll_bg_pixel, NULL);
  1629.  
  1630.     XtAddCallback(dialog_wgt, XmNokCallback, DialogAcceptCB, (XtPointer)0);
  1631.     XtAddCallback(dialog_wgt, XmNcancelCallback, DialogCancelCB, (XtPointer)0);
  1632.     /* We have no help in this window, so hide help button */
  1633.     XtUnmanageChild(XmFileSelectionBoxGetChild(dialog_wgt,
  1634.                     (unsigned char)XmDIALOG_HELP_BUTTON));
  1635.  
  1636.     manage_centered(dialog_wgt);
  1637.  
  1638.     /* sit in a loop until the dialog box has gone away */
  1639.     do
  1640.     {
  1641.     XtAppProcessEvent(XtWidgetToApplicationContext(dialog_wgt),
  1642.         (XtInputMask)XtIMAll);
  1643.     } while (XtIsManaged(dialog_wgt));
  1644.  
  1645.     XtDestroyWidget(dialog_wgt);
  1646.     vim_free(tofree);
  1647.  
  1648.     if (browse_fname == NULL)
  1649.     return NULL;
  1650.     return vim_strsave((char_u *)browse_fname);
  1651. }
  1652.  
  1653. /*
  1654.  * The code below was originally taken from
  1655.  *    /usr/examples/motif/xmsamplers/xmeditor.c
  1656.  * on Digital Unix 4.0d, but heavily modified.
  1657.  */
  1658.  
  1659. /*
  1660.  * Process callback from Dialog cancel actions.
  1661.  */
  1662. /* ARGSUSED */
  1663.     static void
  1664. DialogCancelCB(w, client_data, call_data)
  1665.     Widget    w;        /*  widget id        */
  1666.     XtPointer    client_data;    /*  data from application   */
  1667.     XtPointer    call_data;    /*  data from widget class  */
  1668. {
  1669.     if (browse_fname != NULL)
  1670.     {
  1671.     XtFree(browse_fname);
  1672.     browse_fname = NULL;
  1673.     }
  1674.     XtUnmanageChild(dialog_wgt);
  1675. }
  1676.  
  1677. /*
  1678.  * Process callback from Dialog actions.
  1679.  */
  1680. /* ARGSUSED */
  1681.     static void
  1682. DialogAcceptCB(w, client_data, call_data)
  1683.     Widget    w;        /*  widget id        */
  1684.     XtPointer    client_data;    /*  data from application   */
  1685.     XtPointer    call_data;    /*  data from widget class  */
  1686. {
  1687.     XmFileSelectionBoxCallbackStruct *fcb;
  1688.  
  1689.     if (browse_fname != NULL)
  1690.     {
  1691.     XtFree(browse_fname);
  1692.     browse_fname = NULL;
  1693.     }
  1694.     fcb = (XmFileSelectionBoxCallbackStruct *)call_data;
  1695.  
  1696.     /* get the filename from the file selection box */
  1697.     XmStringGetLtoR(fcb->value, charset, &browse_fname);
  1698.  
  1699.     /* popdown the file selection box */
  1700.     XtUnmanageChild(dialog_wgt);
  1701. }
  1702.  
  1703. #endif /* FEAT_BROWSE */
  1704.  
  1705. #if defined(FEAT_GUI_DIALOG) || defined(PROTO)
  1706.  
  1707. static int    dialogStatus;
  1708.  
  1709. static void keyhit_callback __ARGS((Widget w, XtPointer client_data, XEvent *event, Boolean *cont));
  1710. static void butproc __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
  1711.  
  1712. /*
  1713.  * Callback function for the textfield.  When CR is hit this works like
  1714.  * hitting the "OK" button, ESC like "Cancel".
  1715.  */
  1716. /* ARGSUSED */
  1717.     static void
  1718. keyhit_callback(w, client_data, event, cont)
  1719.     Widget        w;
  1720.     XtPointer        client_data;
  1721.     XEvent        *event;
  1722.     Boolean        *cont;
  1723. {
  1724.     char    buf[2];
  1725.     KeySym    key_sym;
  1726.  
  1727.     if (XLookupString(&(event->xkey), buf, 2, &key_sym, NULL) == 1)
  1728.     {
  1729.     if (*buf == CR)
  1730.         dialogStatus = 1;
  1731.     else if (*buf == ESC)
  1732.         dialogStatus = 2;
  1733.     }
  1734.     if ((key_sym == XK_Left || key_sym == XK_Right)
  1735.         && !(event->xkey.state & ShiftMask))
  1736.     XmTextFieldClearSelection(w, XtLastTimestampProcessed(gui.dpy));
  1737. }
  1738.  
  1739. /* ARGSUSED */
  1740.     static void
  1741. butproc(w, client_data, call_data)
  1742.     Widget    w;
  1743.     XtPointer    client_data;
  1744.     XtPointer    call_data;
  1745. {
  1746.     dialogStatus = (int)(long)client_data + 1;
  1747. }
  1748.  
  1749. static void gui_motif_set_fontlist __ARGS((Widget wg));
  1750.  
  1751. /*
  1752.  * Use the 'guifont' or 'guifontset' as a fontlist for a dialog widget.
  1753.  */
  1754.     static void
  1755. gui_motif_set_fontlist(wg)
  1756.     Widget wg;
  1757. {
  1758.     XmFontList fl;
  1759.  
  1760.     fl =
  1761. #ifdef FEAT_XFONTSET
  1762.         gui.fontset != NOFONTSET ?
  1763.             gui_motif_fontset2fontlist((XFontSet *)&gui.fontset)
  1764.                      :
  1765. #endif
  1766.             gui_motif_create_fontlist((XFontStruct *)gui.norm_font);
  1767.     if (fl != NULL)
  1768.     {
  1769.     XtVaSetValues(wg, XmNfontList, fl, NULL);
  1770.     XmFontListFree(fl);
  1771.     }
  1772. }
  1773.  
  1774. #ifdef HAVE_XPM
  1775.  
  1776. static Widget create_pixmap_label(Widget parent, String name, char **data, ArgList args, Cardinal arg);
  1777.  
  1778.     static Widget
  1779. create_pixmap_label(parent, name, data, args, arg)
  1780.     Widget    parent;
  1781.     String    name;
  1782.     char    **data;
  1783.     ArgList    args;
  1784.     Cardinal    arg;
  1785. {
  1786.     Widget        label;
  1787.     Display        *dsp;
  1788.     Screen        *scr;
  1789.     int            depth;
  1790.     Pixmap        pixmap = 0;
  1791.     XpmAttributes    attr;
  1792.     Boolean        rs;
  1793.     XpmColorSymbol    color[5] =
  1794.     {
  1795.     {"none", NULL, 0},
  1796.     {"iconColor1", NULL, 0},
  1797.     {"bottomShadowColor", NULL, 0},
  1798.     {"topShadowColor", NULL, 0},
  1799.     {"selectColor", NULL, 0}
  1800.     };
  1801.  
  1802.     label = XmCreateLabelGadget(parent, name, args, arg);
  1803.  
  1804.     /*
  1805.      * We need to be carefull here, since in case of gadgets, there is
  1806.      * no way to get the background color directly from the widget itself.
  1807.      * In such cases we get it from The Core part of his parent instead.
  1808.      */
  1809.     dsp = XtDisplayOfObject(label);
  1810.     scr = XtScreenOfObject(label);
  1811.     XtVaGetValues(XtIsSubclass(label, coreWidgetClass)
  1812.         ?  label : XtParent(label),
  1813.           XmNdepth, &depth,
  1814.           XmNbackground, &color[0].pixel,
  1815.           XmNforeground, &color[1].pixel,
  1816.           XmNbottomShadowColor, &color[2].pixel,
  1817.           XmNtopShadowColor, &color[3].pixel,
  1818.           XmNhighlight, &color[4].pixel,
  1819.           NULL);
  1820.  
  1821.     attr.valuemask = XpmColorSymbols | XpmCloseness | XpmDepth;
  1822.     attr.colorsymbols = color;
  1823.     attr.numsymbols = 5;
  1824.     attr.closeness = 65535;
  1825.     attr.depth = depth;
  1826.     XpmCreatePixmapFromData(dsp, RootWindowOfScreen(scr),
  1827.             data, &pixmap, NULL, &attr);
  1828.  
  1829.     XtVaGetValues(label, XmNrecomputeSize, &rs, NULL);
  1830.     XtVaSetValues(label, XmNrecomputeSize, True, NULL);
  1831.     XtVaSetValues(label,
  1832.         XmNlabelType, XmPIXMAP,
  1833.         XmNlabelPixmap, pixmap,
  1834.         NULL);
  1835.     XtVaSetValues(label, XmNrecomputeSize, rs, NULL);
  1836.  
  1837.     return label;
  1838. }
  1839. #endif
  1840.  
  1841. /* ARGSUSED */
  1842.     int
  1843. gui_mch_dialog(type, title, message, button_names, dfltbutton, textfield)
  1844.     int        type;
  1845.     char_u    *title;
  1846.     char_u    *message;
  1847.     char_u    *button_names;
  1848.     int        dfltbutton;
  1849.     char_u    *textfield;        /* buffer of size IOSIZE */
  1850. {
  1851.     char_u        *buts;
  1852.     char_u        *p, *next;
  1853.     XtAppContext    app;
  1854.     XmString        label;
  1855.     int            butcount;
  1856.     Widget        dialogform = NULL;
  1857.     Widget        form = NULL;
  1858.     Widget        dialogtextfield = NULL;
  1859.     Widget        *buttons;
  1860.     Widget        sep_form = NULL;
  1861.     Boolean        vertical;
  1862.     Widget        separator = NULL;
  1863.     int            n;
  1864.     Arg            args[6];
  1865. #ifdef HAVE_XPM
  1866.     char        **icon_data = NULL;
  1867.     Widget        dialogpixmap = NULL;
  1868. #endif
  1869.  
  1870.     if (title == NULL)
  1871.     title = (char_u *)_("Vim dialog");
  1872.  
  1873.     /* if our pointer is currently hidden, then we should show it. */
  1874.     gui_mch_mousehide(FALSE);
  1875.  
  1876.     dialogform = XmCreateFormDialog(vimShell, (char *)"dialog", NULL, 0);
  1877.  
  1878.     /* Check 'v' flag in 'guioptions': vertical button placement. */
  1879.     vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);
  1880.  
  1881.     /* Set the title of the Dialog window */
  1882.     label = XmStringCreateSimple((char *)title);
  1883.     if (label == NULL)
  1884.     return -1;
  1885.     XtVaSetValues(dialogform,
  1886.         XmNdialogTitle, label,
  1887.         XmNhorizontalSpacing, 4,
  1888.         XmNverticalSpacing, vertical ? 0 : 4,
  1889.         NULL);
  1890.     XmStringFree(label);
  1891.  
  1892.     /* make a copy, so that we can insert NULs */
  1893.     buts = vim_strsave(button_names);
  1894.     if (buts == NULL)
  1895.     return -1;
  1896.  
  1897.     /* Count the number of buttons and allocate buttons[]. */
  1898.     butcount = 1;
  1899.     for (p = buts; *p; ++p)
  1900.     if (*p == DLG_BUTTON_SEP)
  1901.         ++butcount;
  1902.     buttons = (Widget *)alloc((unsigned)(butcount * sizeof(Widget)));
  1903.     if (buttons == NULL)
  1904.     {
  1905.     vim_free(buts);
  1906.     return -1;
  1907.     }
  1908.  
  1909.     /*
  1910.      * Create the buttons.
  1911.      */
  1912.     sep_form = (Widget) 0;
  1913.     p = buts;
  1914.     for (butcount = 0; *p; ++butcount)
  1915.     {
  1916.     for (next = p; *next; ++next)
  1917.     {
  1918.         if (*next == DLG_HOTKEY_CHAR)
  1919.         mch_memmove(next, next + 1, STRLEN(next));
  1920.         if (*next == DLG_BUTTON_SEP)
  1921.         {
  1922.         *next++ = NUL;
  1923.         break;
  1924.         }
  1925.     }
  1926.     label = XmStringCreate(_((char *)p), STRING_TAG);
  1927.     if (label == NULL)
  1928.         break;
  1929.  
  1930.     buttons[butcount] = XtVaCreateManagedWidget("button",
  1931.         xmPushButtonWidgetClass, dialogform,
  1932.         XmNlabelString, label,
  1933.         XmNbottomAttachment, XmATTACH_FORM,
  1934.         XmNbottomOffset, 4,
  1935.         XmNshowAsDefault, butcount == dfltbutton - 1,
  1936.         XmNdefaultButtonShadowThickness, 1,
  1937.         NULL);
  1938.     XmStringFree(label);
  1939.  
  1940.     /* Layout properly. */
  1941.  
  1942.     if (butcount > 0)
  1943.     {
  1944.         if (vertical)
  1945.         XtVaSetValues(buttons[butcount],
  1946.             XmNtopWidget, buttons[butcount - 1],
  1947.             NULL);
  1948.         else
  1949.         {
  1950.         if (*next == NUL)
  1951.         {
  1952.             XtVaSetValues(buttons[butcount],
  1953.                 XmNrightAttachment, XmATTACH_FORM,
  1954.                 XmNrightOffset, 4,
  1955.                 NULL);
  1956.  
  1957.             /* fill in a form as invisible separator */
  1958.             sep_form = XtVaCreateWidget("separatorForm",
  1959.                 xmFormWidgetClass,    dialogform,
  1960.                 XmNleftAttachment, XmATTACH_WIDGET,
  1961.                 XmNleftWidget, buttons[butcount - 1],
  1962.                 XmNrightAttachment, XmATTACH_WIDGET,
  1963.                 XmNrightWidget, buttons[butcount],
  1964.                 XmNbottomAttachment, XmATTACH_FORM,
  1965.                 XmNbottomOffset, 4,
  1966.                 NULL);
  1967.             XtManageChild(sep_form);
  1968.         }
  1969.         else
  1970.         {
  1971.             XtVaSetValues(buttons[butcount],
  1972.                 XmNleftAttachment, XmATTACH_WIDGET,
  1973.                 XmNleftWidget, buttons[butcount - 1],
  1974.                 NULL);
  1975.         }
  1976.         }
  1977.     }
  1978.     else if (!vertical)
  1979.     {
  1980.         if (*next == NUL)
  1981.         {
  1982.         XtVaSetValues(buttons[0],
  1983.             XmNrightAttachment, XmATTACH_FORM,
  1984.             XmNrightOffset, 4,
  1985.             NULL);
  1986.  
  1987.         /* fill in a form as invisible separator */
  1988.         sep_form = XtVaCreateWidget("separatorForm",
  1989.             xmFormWidgetClass, dialogform,
  1990.             XmNleftAttachment, XmATTACH_FORM,
  1991.             XmNleftOffset, 4,
  1992.             XmNrightAttachment, XmATTACH_WIDGET,
  1993.             XmNrightWidget, buttons[0],
  1994.             XmNbottomAttachment, XmATTACH_FORM,
  1995.             XmNbottomOffset, 4,
  1996.             NULL);
  1997.         XtManageChild(sep_form);
  1998.         }
  1999.         else
  2000.         XtVaSetValues(buttons[0],
  2001.             XmNleftAttachment, XmATTACH_FORM,
  2002.             XmNleftOffset, 4,
  2003.             NULL);
  2004.     }
  2005.  
  2006.     XtAddCallback(buttons[butcount], XmNactivateCallback,
  2007.               (XtCallbackProc)butproc, (XtPointer)(long)butcount);
  2008.     p = next;
  2009.     }
  2010.     vim_free(buts);
  2011.  
  2012.     separator = (Widget) 0;
  2013.     if (butcount > 0)
  2014.     {
  2015.     /* Create the separator for beauty. */
  2016.     n = 0;
  2017.     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
  2018.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2019.     XtSetArg(args[n], XmNbottomWidget, buttons[0]); n++;
  2020.     XtSetArg(args[n], XmNbottomOffset, 4); n++;
  2021.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2022.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2023.     separator = XmCreateSeparatorGadget(dialogform, "separator", args, n);
  2024.     XtManageChild(separator);
  2025.     }
  2026.  
  2027.     if (textfield != NULL)
  2028.     {
  2029.     dialogtextfield = XtVaCreateWidget("textField",
  2030.         xmTextFieldWidgetClass, dialogform,
  2031.         XmNleftAttachment, XmATTACH_FORM,
  2032.         XmNrightAttachment, XmATTACH_FORM,
  2033.         NULL);
  2034.     if (butcount > 0)
  2035.         XtVaSetValues(dialogtextfield,
  2036.             XmNbottomAttachment, XmATTACH_WIDGET,
  2037.             XmNbottomWidget, separator,
  2038.             NULL);
  2039.     else
  2040.         XtVaSetValues(dialogtextfield,
  2041.             XmNbottomAttachment, XmATTACH_FORM,
  2042.             NULL);
  2043.  
  2044.     gui_motif_set_fontlist(dialogtextfield);
  2045.     XmTextFieldSetString(dialogtextfield, (char *)textfield);
  2046.     XtManageChild(dialogtextfield);
  2047.     XtAddEventHandler(dialogtextfield, KeyPressMask, False,
  2048.                 (XtEventHandler)keyhit_callback, (XtPointer)NULL);
  2049.     }
  2050.  
  2051.     /* Form holding both message and pixmap labels */
  2052.     form = XtVaCreateWidget("separatorForm",
  2053.         xmFormWidgetClass, dialogform,
  2054.         XmNleftAttachment, XmATTACH_FORM,
  2055.         XmNrightAttachment, XmATTACH_FORM,
  2056.         XmNtopAttachment, XmATTACH_FORM,
  2057.         NULL);
  2058.     XtManageChild(form);
  2059.  
  2060. #ifdef HAVE_XPM
  2061.     /* Add a pixmap, left of the message. */
  2062.     switch (type)
  2063.     {
  2064.     case VIM_GENERIC:
  2065.         icon_data = generic_xpm;
  2066.         break;
  2067.     case VIM_ERROR:
  2068.         icon_data = error_xpm;
  2069.         break;
  2070.     case VIM_WARNING:
  2071.         icon_data = alert_xpm;
  2072.         break;
  2073.     case VIM_INFO:
  2074.         icon_data = info_xpm;
  2075.         break;
  2076.     case VIM_QUESTION:
  2077.         icon_data = quest_xpm;
  2078.         break;
  2079.     default:
  2080.         icon_data = generic_xpm;
  2081.     }
  2082.  
  2083.     n = 0;
  2084.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2085.     XtSetArg(args[n], XmNtopOffset, 8); n++;
  2086.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2087.     XtSetArg(args[n], XmNbottomOffset, 8); n++;
  2088.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2089.     XtSetArg(args[n], XmNleftOffset, 8); n++;
  2090.  
  2091.     dialogpixmap = create_pixmap_label(form, "dialogPixmap",
  2092.         icon_data, args, n);
  2093.     XtManageChild(dialogpixmap);
  2094. #endif
  2095.  
  2096.     /* Create the dialog message. */
  2097.     label = XmStringLtoRCreate((char *)message, STRING_TAG);
  2098.     if (label == NULL)
  2099.     return -1;
  2100.     (void)XtVaCreateManagedWidget("dialogMessage",
  2101.                 xmLabelGadgetClass, form,
  2102.                 XmNlabelString, label,
  2103.                 XmNtopAttachment, XmATTACH_FORM,
  2104.                 XmNtopOffset, 8,
  2105. #ifdef HAVE_XPM
  2106.                 XmNleftAttachment, XmATTACH_WIDGET,
  2107.                 XmNleftWidget, dialogpixmap,
  2108. #else
  2109.                 XmNleftAttachment, XmATTACH_FORM,
  2110. #endif
  2111.                 XmNleftOffset, 8,
  2112.                 XmNrightAttachment, XmATTACH_FORM,
  2113.                 XmNrightOffset, 8,
  2114.                 XmNbottomAttachment, XmATTACH_FORM,
  2115.                 XmNbottomOffset, 8,
  2116.                 NULL);
  2117.     XmStringFree(label);
  2118.  
  2119.     if (textfield != NULL)
  2120.     {
  2121.     XtVaSetValues(form,
  2122.         XmNbottomAttachment, XmATTACH_WIDGET,
  2123.         XmNbottomWidget, dialogtextfield,
  2124.         NULL);
  2125.     }
  2126.     else
  2127.     {
  2128.     if (butcount > 0)
  2129.         XtVaSetValues(form,
  2130.             XmNbottomAttachment, XmATTACH_WIDGET,
  2131.             XmNbottomWidget, separator,
  2132.             NULL);
  2133.     else
  2134.         XtVaSetValues(form,
  2135.             XmNbottomAttachment, XmATTACH_FORM,
  2136.             NULL);
  2137.     }
  2138.  
  2139.     if (dfltbutton < 1)
  2140.     dfltbutton = 1;
  2141.     if (dfltbutton > butcount)
  2142.     dfltbutton = butcount;
  2143.     XtVaSetValues(dialogform,
  2144.         XmNdefaultButton, buttons[dfltbutton - 1], NULL);
  2145.     if (textfield != NULL)
  2146.     XtVaSetValues(dialogform, XmNinitialFocus, dialogtextfield, NULL);
  2147.     else
  2148.     XtVaSetValues(dialogform, XmNinitialFocus, buttons[dfltbutton - 1],
  2149.                                     NULL);
  2150.  
  2151.     manage_centered(dialogform);
  2152.  
  2153.     if (textfield != NULL && *textfield != NUL)
  2154.     {
  2155.     /* This only works after the textfield has been realised. */
  2156.     XmTextFieldSetSelection(dialogtextfield,
  2157.              (XmTextPosition)0, (XmTextPosition)STRLEN(textfield),
  2158.                        XtLastTimestampProcessed(gui.dpy));
  2159.     XmTextFieldSetCursorPosition(dialogtextfield,
  2160.                        (XmTextPosition)STRLEN(textfield));
  2161.     }
  2162.  
  2163.     app = XtWidgetToApplicationContext(dialogform);
  2164.  
  2165.     /* Loop until a button is pressed or the dialog is killed somehow. */
  2166.     dialogStatus = -1;
  2167.     for (;;)
  2168.     {
  2169.     XtAppProcessEvent(app, (XtInputMask)XtIMAll);
  2170.     if (dialogStatus >= 0 || !XtIsManaged(dialogform))
  2171.         break;
  2172.     }
  2173.  
  2174.     vim_free(buttons);
  2175.  
  2176.     if (textfield != NULL)
  2177.     {
  2178.     p = (char_u *)XmTextGetString(dialogtextfield);
  2179.     if (p == NULL || dialogStatus < 0)
  2180.         *textfield = NUL;
  2181.     else
  2182.     {
  2183.         STRNCPY(textfield, p, IOSIZE);
  2184.         textfield[IOSIZE - 1] = NUL;
  2185.     }
  2186.     }
  2187.  
  2188.     XtDestroyWidget(dialogform);
  2189.  
  2190.     return dialogStatus;
  2191. }
  2192. #endif /* FEAT_GUI_DIALOG */
  2193.  
  2194. #if defined(FEAT_FOOTER) || defined(PROTO)
  2195.  
  2196.     static int
  2197. gui_mch_compute_footer_height()
  2198. {
  2199.     Dimension    height;            /* total Toolbar height */
  2200.     Dimension    top;            /* XmNmarginTop */
  2201.     Dimension    bottom;            /* XmNmarginBottom */
  2202.     Dimension    shadow;            /* XmNshadowThickness */
  2203.  
  2204.     XtVaGetValues(footer,
  2205.         XmNheight, &height,
  2206.         XmNmarginTop, &top,
  2207.         XmNmarginBottom, &bottom,
  2208.         XmNshadowThickness, &shadow,
  2209.         NULL);
  2210.  
  2211.     return (int) height + top + bottom + (shadow << 1);
  2212. }
  2213.  
  2214. #if 0        /* not used */
  2215.     void
  2216. gui_mch_set_footer_pos(h)
  2217.     int        h;                /* textArea height */
  2218. {
  2219.     XtVaSetValues(footer,
  2220.           XmNtopOffset, h + 7,
  2221.           NULL);
  2222. }
  2223. #endif
  2224.  
  2225.     void
  2226. gui_mch_enable_footer(showit)
  2227.     int        showit;
  2228. {
  2229.     if (showit)
  2230.     {
  2231.     gui.footer_height = gui_mch_compute_footer_height();
  2232.     XtManageChild(footer);
  2233.     }
  2234.     else
  2235.     {
  2236.     gui.footer_height = 0;
  2237.     XtUnmanageChild(footer);
  2238.     }
  2239.     XtVaSetValues(textAreaForm, XmNbottomOffset, gui.footer_height, NULL);
  2240. }
  2241.  
  2242.     void
  2243. gui_mch_set_footer(s)
  2244.     char_u    *s;
  2245. {
  2246.     XmString    xms;
  2247.  
  2248.     xms = XmStringCreate((char *)s, STRING_TAG);
  2249.     XtVaSetValues(footer, XmNlabelString, xms, NULL);
  2250.     XmStringFree(xms);
  2251. }
  2252.  
  2253. #endif
  2254.  
  2255.  
  2256. #if defined(FEAT_TOOLBAR) || defined(PROTO)
  2257.     void
  2258. gui_mch_show_toolbar(int showit)
  2259. {
  2260.     Cardinal    numChildren;        /* how many children toolBar has */
  2261.  
  2262.     if (toolBar == (Widget)0)
  2263.     return;
  2264.     XtVaGetValues(toolBar, XmNnumChildren, &numChildren, NULL);
  2265.     if (showit && numChildren > 0)
  2266.     {
  2267.     /* Assume that we want to show the toolbar if p_toolbar contains
  2268.      * valid option settings, therefore p_toolbar must not be NULL.
  2269.      */
  2270.     WidgetList  children;
  2271.  
  2272.     XtVaGetValues(toolBar, XmNchildren, &children, NULL);
  2273.     {
  2274.         void    (*action)(BalloonEval *);
  2275.         int        text = 0;
  2276.  
  2277.         if (strstr((const char *)p_toolbar, "tooltips"))
  2278.         action = &gui_mch_enable_beval_area;
  2279.         else
  2280.         action = &gui_mch_disable_beval_area;
  2281.         if (strstr((const char *)p_toolbar, "text"))
  2282.         text = 1;
  2283.         else if (strstr((const char *)p_toolbar, "icons"))
  2284.         text = -1;
  2285.         if (text != 0)
  2286.         {
  2287.         vimmenu_T   *toolbar;
  2288.         vimmenu_T   *cur;
  2289.  
  2290.         for (toolbar = root_menu; toolbar; toolbar = toolbar->next)
  2291.             if (menu_is_toolbar(toolbar->dname))
  2292.             break;
  2293.         /* Assumption: toolbar is NULL if there is no toolbar,
  2294.          *           otherwise it contains the toolbar menu structure.
  2295.          *
  2296.          * Assumption: "numChildren" == the number of items in the list
  2297.          *           of items beginning with toolbar->children.
  2298.          */
  2299.         if (toolbar)
  2300.         {
  2301.             for (cur = toolbar->children; cur; cur = cur->next)
  2302.             {
  2303.             Arg        args[1];
  2304.             int        n = 0;
  2305.  
  2306.             /* Enable/Disable tooltip (OK to enable while
  2307.              * currently enabled)
  2308.              */
  2309.             if (cur->tip != NULL)
  2310.                 (*action)(cur->tip);
  2311.             if (!menu_is_separator(cur->name))
  2312.             {
  2313.                 if (text == 1 || cur->image == 0)
  2314.                 XtSetArg(args[n], XmNlabelType, XmSTRING);
  2315.                 else
  2316.                 XtSetArg(args[n], XmNlabelType, XmPIXMAP);
  2317.                 n++;
  2318.                 if (cur->id != NULL)
  2319.                 {
  2320.                 XtUnmanageChild(cur->id);
  2321.                 XtSetValues(cur->id, args, n);
  2322.                 XtManageChild(cur->id);
  2323.                 }
  2324.             }
  2325.             }
  2326.         }
  2327.         }
  2328.     }
  2329.     gui.toolbar_height = gui_mch_compute_toolbar_height();
  2330.     XtManageChild(XtParent(toolBar));
  2331.     XtVaSetValues(textAreaForm,
  2332.         XmNtopAttachment, XmATTACH_WIDGET,
  2333.         XmNtopWidget, XtParent(toolBar),
  2334.         NULL);
  2335.     if (XtIsManaged(menuBar))
  2336.         XtVaSetValues(XtParent(toolBar),
  2337.             XmNtopAttachment, XmATTACH_WIDGET,
  2338.             XmNtopWidget, menuBar,
  2339.             NULL);
  2340.     else
  2341.         XtVaSetValues(XtParent(toolBar),
  2342.             XmNtopAttachment, XmATTACH_FORM,
  2343.             NULL);
  2344.     }
  2345.     else
  2346.     {
  2347.     gui.toolbar_height = 0;
  2348.     if (XtIsManaged(menuBar))
  2349.         XtVaSetValues(textAreaForm,
  2350.         XmNtopAttachment, XmATTACH_WIDGET,
  2351.         XmNtopWidget, menuBar,
  2352.         NULL);
  2353.     else
  2354.         XtVaSetValues(textAreaForm,
  2355.         XmNtopAttachment, XmATTACH_FORM,
  2356.         NULL);
  2357.  
  2358.     XtUnmanageChild(XtParent(toolBar));
  2359.     }
  2360.     gui_set_shellsize(FALSE, FALSE);
  2361. }
  2362.  
  2363. /*
  2364.  * A toolbar button has been pushed; now reset the input focus
  2365.  * such that the user can type page up/down etc. and have the
  2366.  * input go to the editor window, not the button
  2367.  */
  2368.     static void
  2369. gui_mch_reset_focus()
  2370. {
  2371.     if (textArea != NULL)
  2372.     XmProcessTraversal(textArea, XmTRAVERSE_CURRENT);
  2373. }
  2374.  
  2375.     int
  2376. gui_mch_compute_toolbar_height()
  2377. {
  2378.     Dimension    height;            /* total Toolbar height */
  2379.     Dimension    whgt;            /* height of each widget */
  2380.     Dimension    marginHeight;        /* XmNmarginHeight of toolBar */
  2381.     Dimension    shadowThickness;    /* thickness of Xtparent(toolBar) */
  2382.     WidgetList    children;        /* list of toolBar's children */
  2383.     Cardinal    numChildren;        /* how many children toolBar has */
  2384.     int        i;
  2385.  
  2386.     height = 0;
  2387.     shadowThickness = 0;
  2388.     marginHeight = 0;
  2389.     if (toolBar != (Widget)0 && toolBarFrame != (Widget)0)
  2390.     {                    /* get height of XmFrame parent */
  2391.     XtVaGetValues(toolBarFrame,
  2392.         XmNshadowThickness, &shadowThickness,
  2393.         NULL);
  2394.     XtVaGetValues(toolBar,
  2395.         XmNmarginHeight, &marginHeight,
  2396.         XmNchildren, &children,
  2397.         XmNnumChildren, &numChildren, NULL);
  2398.     for (i = 0; i < numChildren; i++)
  2399.     {
  2400.         whgt = 0;
  2401.         XtVaGetValues(children[i], XmNheight, &whgt, NULL);
  2402.         if (height < whgt)
  2403.         height = whgt;
  2404.     }
  2405.     }
  2406.  
  2407.     return (int)(height + (marginHeight << 1) + (shadowThickness << 1));
  2408. }
  2409.  
  2410. #if 0 /* these are never called. */
  2411. /*
  2412.  * The next toolbar enter/leave callbacks make sure the text area gets the
  2413.  * keyboard focus when the pointer is not in the toolbar.
  2414.  */
  2415. /*ARGSUSED*/
  2416.     static void
  2417. toolbar_enter_cb(w, client_data, event, cont)
  2418.     Widget    w;
  2419.     XtPointer    client_data;
  2420.     XEvent    *event;
  2421.     Boolean    *cont;
  2422. {
  2423.     XmProcessTraversal(toolBar, XmTRAVERSE_CURRENT);
  2424. }
  2425.  
  2426. /*ARGSUSED*/
  2427.     static void
  2428. toolbar_leave_cb(w, client_data, event, cont)
  2429.     Widget    w;
  2430.     XtPointer    client_data;
  2431.     XEvent    *event;
  2432.     Boolean    *cont;
  2433. {
  2434.     XmProcessTraversal(textArea, XmTRAVERSE_CURRENT);
  2435. }
  2436. #endif
  2437.  
  2438. # ifdef FEAT_FOOTER
  2439. /*
  2440.  * The next toolbar enter/leave callbacks should really do balloon help.  But
  2441.  * I have to use footer help for backwards compatability.  Hopefully both will
  2442.  * get implemented and the user will have a choice.
  2443.  */
  2444. /*ARGSUSED*/
  2445.     static void
  2446. toolbarbutton_enter_cb(w, client_data, event, cont)
  2447.     Widget    w;
  2448.     XtPointer    client_data;
  2449.     XEvent    *event;
  2450.     Boolean    *cont;
  2451. {
  2452.     vimmenu_T    *menu = (vimmenu_T *) client_data;
  2453.  
  2454.     if (menu->strings[MENU_INDEX_TIP] != NULL)
  2455.     {
  2456.     if (vim_strchr(p_go, GO_FOOTER) != NULL)
  2457.         gui_mch_set_footer(menu->strings[MENU_INDEX_TIP]);
  2458.     }
  2459. }
  2460.  
  2461. /*ARGSUSED*/
  2462.     static void
  2463. toolbarbutton_leave_cb(w, client_data, event, cont)
  2464.     Widget    w;
  2465.     XtPointer    client_data;
  2466.     XEvent    *event;
  2467.     Boolean    *cont;
  2468. {
  2469.     gui_mch_set_footer((char_u *) "");
  2470. }
  2471. # endif
  2472.  
  2473.     void
  2474. gui_mch_get_toolbar_colors(bgp, fgp, bsp, tsp, hsp)
  2475.     Pixel    *bgp;
  2476.     Pixel    *fgp;
  2477.     Pixel       *bsp;
  2478.     Pixel    *tsp;
  2479.     Pixel    *hsp;
  2480. {
  2481.     XtVaGetValues(toolBar,
  2482.         XmNbackground, bgp,
  2483.         XmNforeground, fgp,
  2484.         XmNbottomShadowColor, bsp,
  2485.         XmNtopShadowColor, tsp,
  2486.         XmNhighlightColor, hsp,
  2487.         NULL);
  2488. }
  2489. #endif
  2490.  
  2491. /*
  2492.  * Set the colors of Widget "id" to the menu colors.
  2493.  */
  2494.     static void
  2495. gui_motif_menu_colors(id)
  2496.     Widget  id;
  2497. {
  2498.     if (gui.menu_bg_pixel != INVALCOLOR)
  2499. #if (XmVersion >= 1002)
  2500.     XmChangeColor(id, gui.menu_bg_pixel);
  2501. #else
  2502.     XtVaSetValues(id, XmNbackground, gui.menu_bg_pixel, NULL);
  2503. #endif
  2504.     if (gui.menu_fg_pixel != INVALCOLOR)
  2505.     XtVaSetValues(id, XmNforeground, gui.menu_fg_pixel, NULL);
  2506. }
  2507.  
  2508. /*
  2509.  * Set the colors of Widget "id" to the scrollbar colors.
  2510.  */
  2511.     static void
  2512. gui_motif_scroll_colors(id)
  2513.     Widget  id;
  2514. {
  2515.     if (gui.scroll_bg_pixel != INVALCOLOR)
  2516. #if (XmVersion >= 1002)
  2517.     XmChangeColor(id, gui.scroll_bg_pixel);
  2518. #else
  2519.     XtVaSetValues(id, XmNbackground, gui.scroll_bg_pixel, NULL);
  2520. #endif
  2521.     if (gui.scroll_fg_pixel != INVALCOLOR)
  2522.     XtVaSetValues(id, XmNforeground, gui.scroll_fg_pixel, NULL);
  2523. }
  2524.  
  2525. #ifdef FEAT_MENU
  2526. /*
  2527.  * Set the fontlist for Widget "id" to use gui.menu_fontset or gui.menu_font.
  2528.  */
  2529.     static void
  2530. gui_motif_menu_fontlist(id)
  2531.     Widget  id;
  2532. {
  2533. #ifdef FONTSET_ALWAYS
  2534.     if (gui.menu_fontset != NOFONTSET)
  2535.     {
  2536.     XmFontList fl;
  2537.  
  2538.     fl = gui_motif_fontset2fontlist((XFontSet *)&gui.menu_fontset);
  2539.     if (fl != NULL)
  2540.     {
  2541.         if (XtIsManaged(id))
  2542.         {
  2543.         XtUnmanageChild(id);
  2544.         XtVaSetValues(id, XmNfontList, fl, NULL);
  2545.         /* We should force the widget to recalculate it's
  2546.          * geometry now. */
  2547.         XtManageChild(id);
  2548.         }
  2549.         else
  2550.         XtVaSetValues(id, XmNfontList, fl, NULL);
  2551.         XmFontListFree(fl);
  2552.     }
  2553.     }
  2554. #else
  2555.     if (gui.menu_font != NOFONT)
  2556.     {
  2557.     XmFontList fl;
  2558.  
  2559.     fl = gui_motif_create_fontlist((XFontStruct *)gui.menu_font);
  2560.     if (fl != NULL)
  2561.     {
  2562.         if (XtIsManaged(id))
  2563.         {
  2564.         XtUnmanageChild(id);
  2565.         XtVaSetValues(id, XmNfontList, fl, NULL);
  2566.         /* We should force the widget to recalculate it's
  2567.          * geometry now. */
  2568.         XtManageChild(id);
  2569.         }
  2570.         else
  2571.         XtVaSetValues(id, XmNfontList, fl, NULL);
  2572.         XmFontListFree(fl);
  2573.     }
  2574.     }
  2575. #endif
  2576. }
  2577.  
  2578. #endif
  2579.  
  2580. /*
  2581.  * We don't create it twice for the sake of speed.
  2582.  */
  2583.  
  2584. typedef struct _SharedFindReplace
  2585. {
  2586.     Widget dialog;    /* the main dialog widget */
  2587.     Widget wword;    /* 'Exact match' check button */
  2588.     Widget mcase;    /* 'match case' check button */
  2589.     Widget up;        /* search direction 'Up' radio button */
  2590.     Widget down;    /* search direction 'Down' radio button */
  2591.     Widget what;    /* 'Find what' entry text widget */
  2592.     Widget with;    /* 'Replace with' entry text widget */
  2593.     Widget find;    /* 'Find Next' action button */
  2594.     Widget replace;    /* 'Replace With' action button */
  2595.     Widget all;        /* 'Replace All' action button */
  2596.     Widget undo;    /* 'Undo' action button */
  2597.  
  2598.     Widget cancel;
  2599. } SharedFindReplace;
  2600.  
  2601. static SharedFindReplace find_widgets = { NULL };
  2602. static SharedFindReplace repl_widgets = { NULL };
  2603.  
  2604. static void find_replace_destroy_callback __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
  2605. static void find_replace_dismiss_callback __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
  2606. static void entry_activate_callback __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
  2607. static void find_replace_callback __ARGS((Widget w, XtPointer client_data, XtPointer call_data));
  2608. static void find_replace_keypress __ARGS((Widget w, SharedFindReplace * frdp, XKeyEvent * event));
  2609. static void find_replace_dialog_create __ARGS((char_u *entry_text, int do_replace));
  2610.  
  2611. /*ARGSUSED*/
  2612.     static void
  2613. find_replace_destroy_callback(w, client_data, call_data)
  2614.     Widget    w;
  2615.     XtPointer    client_data;
  2616.     XtPointer    call_data;
  2617. {
  2618.     SharedFindReplace *cd = (SharedFindReplace *)client_data;
  2619.  
  2620.     if (cd != NULL)
  2621.     cd->dialog = (Widget)0;
  2622. }
  2623.  
  2624. /*ARGSUSED*/
  2625.     static void
  2626. find_replace_dismiss_callback(w, client_data, call_data)
  2627.     Widget    w;
  2628.     XtPointer    client_data;
  2629.     XtPointer    call_data;
  2630. {
  2631.     SharedFindReplace *cd = (SharedFindReplace *)client_data;
  2632.  
  2633.     if (cd != NULL)
  2634.     XtUnmanageChild(cd->dialog);
  2635. }
  2636.  
  2637. /*ARGSUSED*/
  2638.     static void
  2639. entry_activate_callback(w, client_data, call_data)
  2640.     Widget    w;
  2641.     XtPointer    client_data;
  2642.     XtPointer    call_data;
  2643. {
  2644.     XmProcessTraversal((Widget)client_data, XmTRAVERSE_CURRENT);
  2645. }
  2646.  
  2647. /*ARGSUSED*/
  2648.     static void
  2649. find_replace_callback(w, client_data, call_data)
  2650.     Widget    w;
  2651.     XtPointer    client_data;
  2652.     XtPointer    call_data;
  2653. {
  2654.     long_u    flags = (long_u)client_data;
  2655.     char    *find_text, *repl_text;
  2656.     Boolean    direction_down = TRUE;
  2657.     Boolean    wword;
  2658.     Boolean    mcase;
  2659.     SharedFindReplace *sfr;
  2660.  
  2661.     if (flags == FRD_UNDO)
  2662.     {
  2663.     char_u    *save_cpo = p_cpo;
  2664.  
  2665.     /* No need to be Vi compatible here. */
  2666.     p_cpo = (char_u *)"";
  2667.     u_undo(1);
  2668.     p_cpo = save_cpo;
  2669.     gui_update_screen();
  2670.     return;
  2671.     }
  2672.  
  2673.     /* Get the search/replace strings from the dialog */
  2674.     if (flags == FRD_FINDNEXT)
  2675.     {
  2676.     repl_text = NULL;
  2677.     sfr = &find_widgets;
  2678.     }
  2679.     else
  2680.     {
  2681.     repl_text = XmTextFieldGetString(repl_widgets.with);
  2682.     sfr = &repl_widgets;
  2683.     }
  2684.     find_text = XmTextFieldGetString(sfr->what);
  2685.     XtVaGetValues(sfr->down, XmNset, &direction_down, NULL);
  2686.     XtVaGetValues(sfr->wword, XmNset, &wword, NULL);
  2687.     XtVaGetValues(sfr->mcase, XmNset, &mcase, NULL);
  2688.     if (wword)
  2689.     flags |= FRD_WHOLE_WORD;
  2690.     if (mcase)
  2691.     flags |= FRD_MATCH_CASE;
  2692.  
  2693.     (void)gui_do_findrepl((int)flags, (char_u *)find_text, (char_u *)repl_text,
  2694.                                   direction_down);
  2695.  
  2696.     if (find_text != NULL)
  2697.     XtFree(find_text);
  2698.     if (repl_text != NULL)
  2699.     XtFree(repl_text);
  2700. }
  2701.  
  2702. /*ARGSUSED*/
  2703.     static void
  2704. find_replace_keypress(w, frdp, event)
  2705.     Widget        w;
  2706.     SharedFindReplace    *frdp;
  2707.     XKeyEvent        *event;
  2708. {
  2709.     KeySym keysym;
  2710.  
  2711.     if (frdp == NULL)
  2712.     return;
  2713.  
  2714.     keysym = XLookupKeysym(event, 0);
  2715.  
  2716.     /* the scape key pops the whole dialog down */
  2717.     if (keysym == XK_Escape)
  2718.     XtUnmanageChild(frdp->dialog);
  2719. }
  2720.  
  2721.     static void
  2722. find_replace_dialog_create(arg, do_replace)
  2723.     char_u    *arg;
  2724.     int        do_replace;
  2725. {
  2726.     SharedFindReplace    *frdp;
  2727.     Widget        separator;
  2728.     Widget        input_form;
  2729.     Widget        button_form;
  2730.     Widget        toggle_form;
  2731.     Widget        frame;
  2732.     XmString        str;
  2733.     int            n;
  2734.     Arg            args[6];
  2735.     int            wword = FALSE;
  2736.     int            mcase = !p_ic;
  2737.     Dimension        width;
  2738.     Dimension        widest;
  2739.     char_u        *entry_text;
  2740.  
  2741.     frdp = do_replace ? &repl_widgets : &find_widgets;
  2742.  
  2743.     /* Get the search string to use. */
  2744.     entry_text = get_find_dialog_text(arg, &wword, &mcase);
  2745.  
  2746.     /* If the dialog already exists, just raise it. */
  2747.     if (frdp->dialog)
  2748.     {
  2749.     /* If the window is already up, just pop it to the top */
  2750.     if (XtIsManaged(frdp->dialog))
  2751.         XMapRaised(XtDisplay(frdp->dialog),
  2752.                         XtWindow(XtParent(frdp->dialog)));
  2753.     else
  2754.         XtManageChild(frdp->dialog);
  2755.     XtPopup(XtParent(frdp->dialog), XtGrabNone);
  2756.     XmProcessTraversal(frdp->what, XmTRAVERSE_CURRENT);
  2757.  
  2758.     if (entry_text != NULL)
  2759.         XmTextFieldSetString(frdp->what, (char *)entry_text);
  2760.     vim_free(entry_text);
  2761.  
  2762.     XtVaSetValues(frdp->wword, XmNset, wword, NULL);
  2763.     return;
  2764.     }
  2765.  
  2766.     /* Create a fresh new dialog window */
  2767.     if (do_replace)
  2768.      str = XmStringCreateSimple(_("VIM - Search and Replace..."));
  2769.     else
  2770.      str = XmStringCreateSimple(_("VIM - Search..."));
  2771.  
  2772.     n = 0;
  2773.     XtSetArg(args[n], XmNautoUnmanage, False); n++;
  2774.     XtSetArg(args[n], XmNnoResize, True); n++;
  2775.     XtSetArg(args[n], XmNdialogTitle, str); n++;
  2776.  
  2777.     frdp->dialog = XmCreateFormDialog(vimShell, "findReplaceDialog", args, n);
  2778.     XmStringFree(str);
  2779.     XtAddCallback(frdp->dialog, XmNdestroyCallback,
  2780.         find_replace_destroy_callback, frdp);
  2781.  
  2782.     button_form = XtVaCreateWidget("buttonForm",
  2783.         xmFormWidgetClass,    frdp->dialog,
  2784.         XmNrightAttachment, XmATTACH_FORM,
  2785.         XmNrightOffset, 4,
  2786.         XmNtopAttachment, XmATTACH_FORM,
  2787.         XmNtopOffset, 4,
  2788.         XmNbottomAttachment, XmATTACH_FORM,
  2789.         XmNbottomOffset, 4,
  2790.         NULL);
  2791.  
  2792.     str = XmStringCreateSimple(_("Find Next"));
  2793.     frdp->find = XtVaCreateManagedWidget("findButton",
  2794.         xmPushButtonWidgetClass, button_form,
  2795.         XmNlabelString, str,
  2796.         XmNsensitive, True,
  2797.         XmNtopAttachment, XmATTACH_FORM,
  2798.         XmNleftAttachment, XmATTACH_FORM,
  2799.         XmNrightAttachment, XmATTACH_FORM,
  2800.         NULL);
  2801.     XmStringFree(str);
  2802.  
  2803.     XtAddCallback(frdp->find, XmNactivateCallback,
  2804.         find_replace_callback,
  2805.         (XtPointer) (do_replace ? FRD_R_FINDNEXT : FRD_FINDNEXT));
  2806.  
  2807.     if (do_replace)
  2808.     {
  2809.     str = XmStringCreateSimple(_("Replace"));
  2810.     frdp->replace = XtVaCreateManagedWidget("replaceButton",
  2811.         xmPushButtonWidgetClass, button_form,
  2812.         XmNlabelString, str,
  2813.         XmNtopAttachment, XmATTACH_WIDGET,
  2814.         XmNtopWidget, frdp->find,
  2815.         XmNleftAttachment, XmATTACH_FORM,
  2816.         XmNrightAttachment, XmATTACH_FORM,
  2817.         NULL);
  2818.     XmStringFree(str);
  2819.     XtAddCallback(frdp->replace, XmNactivateCallback,
  2820.         find_replace_callback, (XtPointer)FRD_REPLACE);
  2821.  
  2822.     str = XmStringCreateSimple(_("Replace All"));
  2823.     frdp->all = XtVaCreateManagedWidget("replaceAllButton",
  2824.         xmPushButtonWidgetClass, button_form,
  2825.         XmNlabelString, str,
  2826.         XmNtopAttachment, XmATTACH_WIDGET,
  2827.         XmNtopWidget, frdp->replace,
  2828.         XmNleftAttachment, XmATTACH_FORM,
  2829.         XmNrightAttachment, XmATTACH_FORM,
  2830.         NULL);
  2831.     XmStringFree(str);
  2832.     XtAddCallback(frdp->all, XmNactivateCallback,
  2833.         find_replace_callback, (XtPointer)FRD_REPLACEALL);
  2834.  
  2835.     str = XmStringCreateSimple(_("Undo"));
  2836.     frdp->undo = XtVaCreateManagedWidget("undoButton",
  2837.         xmPushButtonWidgetClass, button_form,
  2838.         XmNlabelString, str,
  2839.         XmNtopAttachment, XmATTACH_WIDGET,
  2840.         XmNtopWidget, frdp->all,
  2841.         XmNleftAttachment, XmATTACH_FORM,
  2842.         XmNrightAttachment, XmATTACH_FORM,
  2843.         NULL);
  2844.     XmStringFree(str);
  2845.     XtAddCallback(frdp->undo, XmNactivateCallback,
  2846.         find_replace_callback, (XtPointer)FRD_UNDO);
  2847.     }
  2848.  
  2849.     str = XmStringCreateSimple(_("Cancel"));
  2850.     frdp->cancel = XtVaCreateManagedWidget("closeButton",
  2851.         xmPushButtonWidgetClass, button_form,
  2852.         XmNlabelString, str,
  2853.         XmNleftAttachment, XmATTACH_FORM,
  2854.         XmNrightAttachment, XmATTACH_FORM,
  2855.         XmNbottomAttachment, XmATTACH_FORM,
  2856.         NULL);
  2857.     XmStringFree(str);
  2858.     XtAddCallback(frdp->cancel, XmNactivateCallback,
  2859.         find_replace_dismiss_callback, frdp);
  2860.  
  2861.     XtManageChild(button_form);
  2862.  
  2863.     n = 0;
  2864.     XtSetArg(args[n], XmNorientation, XmVERTICAL); n++;
  2865.     XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
  2866.     XtSetArg(args[n], XmNrightWidget, button_form); n++;
  2867.     XtSetArg(args[n], XmNrightOffset, 4); n++;
  2868.     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2869.     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2870.     separator = XmCreateSeparatorGadget(frdp->dialog, "separator", args, n);
  2871.     XtManageChild(separator);
  2872.  
  2873.     input_form = XtVaCreateWidget("inputForm",
  2874.         xmFormWidgetClass,    frdp->dialog,
  2875.         XmNleftAttachment, XmATTACH_FORM,
  2876.         XmNleftOffset, 4,
  2877.         XmNrightAttachment, XmATTACH_WIDGET,
  2878.         XmNrightWidget, separator,
  2879.         XmNrightOffset, 4,
  2880.         XmNtopAttachment, XmATTACH_FORM,
  2881.         XmNtopOffset, 4,
  2882.         NULL);
  2883.  
  2884.     {
  2885.     Widget label_what;
  2886.     Widget label_with = (Widget)0;
  2887.  
  2888.     str = XmStringCreateSimple(_("Find what:"));
  2889.     label_what = XtVaCreateManagedWidget("whatLabel",
  2890.         xmLabelGadgetClass, input_form,
  2891.         XmNlabelString, str,
  2892.         XmNleftAttachment,    XmATTACH_FORM,
  2893.         XmNtopAttachment, XmATTACH_FORM,
  2894.         XmNtopOffset, 4,
  2895.         NULL);
  2896.     XmStringFree(str);
  2897.  
  2898.     frdp->what = XtVaCreateManagedWidget("whatText",
  2899.         xmTextFieldWidgetClass, input_form,
  2900.         XmNtopAttachment, XmATTACH_FORM,
  2901.         XmNrightAttachment, XmATTACH_FORM,
  2902.         XmNleftAttachment, XmATTACH_FORM,
  2903.         NULL);
  2904.  
  2905.     if (do_replace)
  2906.     {
  2907.         frdp->with = XtVaCreateManagedWidget("withText",
  2908.             xmTextFieldWidgetClass,    input_form,
  2909.             XmNtopAttachment, XmATTACH_WIDGET,
  2910.             XmNtopWidget, frdp->what,
  2911.             XmNtopOffset, 4,
  2912.             XmNleftAttachment, XmATTACH_FORM,
  2913.             XmNrightAttachment, XmATTACH_FORM,
  2914.             XmNbottomAttachment, XmATTACH_FORM,
  2915.             NULL);
  2916.  
  2917.         XtAddCallback(frdp->with, XmNactivateCallback,
  2918.             find_replace_callback, (XtPointer) FRD_R_FINDNEXT);
  2919.  
  2920.         str = XmStringCreateSimple(_("Replace with:"));
  2921.         label_with = XtVaCreateManagedWidget("withLabel",
  2922.             xmLabelGadgetClass, input_form,
  2923.             XmNlabelString, str,
  2924.             XmNleftAttachment, XmATTACH_FORM,
  2925.             XmNtopAttachment, XmATTACH_WIDGET,
  2926.             XmNtopWidget, frdp->what,
  2927.             XmNtopOffset, 4,
  2928.             XmNbottomAttachment, XmATTACH_FORM,
  2929.             NULL);
  2930.         XmStringFree(str);
  2931.  
  2932.         /*
  2933.          * Make the entry activation only change the input focus onto the
  2934.          * with item.
  2935.          */
  2936.         XtAddCallback(frdp->what, XmNactivateCallback,
  2937.             entry_activate_callback, frdp->with);
  2938.         XtAddEventHandler(frdp->with, KeyPressMask, False,
  2939.                 (XtEventHandler)find_replace_keypress,
  2940.                 (XtPointer) frdp);
  2941.  
  2942.     }
  2943.     else
  2944.     {
  2945.         /*
  2946.          * Make the entry activation do the search.
  2947.          */
  2948.         XtAddCallback(frdp->what, XmNactivateCallback,
  2949.             find_replace_callback, (XtPointer)FRD_FINDNEXT);
  2950.     }
  2951.     XtAddEventHandler(frdp->what, KeyPressMask, False,
  2952.                 (XtEventHandler)find_replace_keypress,
  2953.                 (XtPointer)frdp);
  2954.  
  2955.     /* Get the maximum width between the label widgets and line them up.
  2956.      */
  2957.     n = 0;
  2958.     XtSetArg(args[n], XmNwidth, &width); n++;
  2959.     XtGetValues(label_what, args, n);
  2960.     widest = width;
  2961.     if (do_replace)
  2962.     {
  2963.         XtGetValues(label_with, args, n);
  2964.         if (width > widest)
  2965.         widest = width;
  2966.     }
  2967.  
  2968.     XtVaSetValues(frdp->what, XmNleftOffset, widest, NULL);
  2969.     if (do_replace)
  2970.         XtVaSetValues(frdp->with, XmNleftOffset, widest, NULL);
  2971.  
  2972.     }
  2973.  
  2974.     XtManageChild(input_form);
  2975.  
  2976.     {
  2977.     Widget radio_box;
  2978.  
  2979.     frame = XtVaCreateWidget("directionFrame",
  2980.         xmFrameWidgetClass, frdp->dialog,
  2981.         XmNtopAttachment, XmATTACH_WIDGET,
  2982.         XmNtopWidget, input_form,
  2983.         XmNtopOffset, 4,
  2984.         XmNbottomAttachment, XmATTACH_FORM,
  2985.         XmNbottomOffset, 4,
  2986.         XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
  2987.         XmNrightWidget, input_form,
  2988.         NULL);
  2989.  
  2990.     str = XmStringCreateSimple(_("Direction"));
  2991.     (void)XtVaCreateManagedWidget("directionFrameLabel",
  2992.         xmLabelGadgetClass, frame,
  2993.         XmNlabelString, str,
  2994.         XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING,
  2995.         XmNchildType, XmFRAME_TITLE_CHILD,
  2996.         NULL);
  2997.     XmStringFree(str);
  2998.  
  2999.     radio_box = XmCreateRadioBox(frame, "radioBox",
  3000.         (ArgList)NULL, 0);
  3001.  
  3002.     str = XmStringCreateSimple( _("Up"));
  3003.     frdp->up = XtVaCreateManagedWidget("upRadioButton",
  3004.         xmToggleButtonGadgetClass, radio_box,
  3005.         XmNlabelString, str,
  3006.         XmNset, False,
  3007.         NULL);
  3008.     XmStringFree(str);
  3009.  
  3010.     str = XmStringCreateSimple(_("Down"));
  3011.     frdp->down = XtVaCreateManagedWidget("downRadioButton",
  3012.         xmToggleButtonGadgetClass, radio_box,
  3013.         XmNlabelString, str,
  3014.         XmNset, True,
  3015.         NULL);
  3016.     XmStringFree(str);
  3017.  
  3018.     XtManageChild(radio_box);
  3019.     XtManageChild(frame);
  3020.     }
  3021.  
  3022.     toggle_form = XtVaCreateWidget("toggleForm",
  3023.         xmFormWidgetClass,    frdp->dialog,
  3024.         XmNleftAttachment, XmATTACH_FORM,
  3025.         XmNleftOffset, 4,
  3026.         XmNrightAttachment, XmATTACH_WIDGET,
  3027.         XmNrightWidget, frame,
  3028.         XmNrightOffset, 4,
  3029.         XmNtopAttachment, XmATTACH_WIDGET,
  3030.         XmNtopWidget, input_form,
  3031.         XmNtopOffset, 4,
  3032.         XmNbottomAttachment, XmATTACH_FORM,
  3033.         XmNbottomOffset, 4,
  3034.         NULL);
  3035.  
  3036.     str = XmStringCreateSimple(_("Match whole word only"));
  3037.     frdp->wword = XtVaCreateManagedWidget("wordToggle",
  3038.         xmToggleButtonGadgetClass, toggle_form,
  3039.         XmNlabelString, str,
  3040.         XmNtopAttachment, XmATTACH_FORM,
  3041.         XmNtopOffset, 4,
  3042.         XmNleftAttachment, XmATTACH_FORM,
  3043.         XmNleftOffset, 4,
  3044.         XmNset, wword,
  3045.         NULL);
  3046.     XmStringFree(str);
  3047.  
  3048.     str = XmStringCreateSimple(_("Match case"));
  3049.     frdp->mcase = XtVaCreateManagedWidget("caseToggle",
  3050.         xmToggleButtonGadgetClass, toggle_form,
  3051.         XmNlabelString, str,
  3052.         XmNleftAttachment, XmATTACH_FORM,
  3053.         XmNleftOffset, 4,
  3054.         XmNtopAttachment, XmATTACH_WIDGET,
  3055.         XmNtopWidget, frdp->wword,
  3056.         XmNtopOffset, 4,
  3057.         XmNset, mcase,
  3058.         NULL);
  3059.     XmStringFree(str);
  3060.  
  3061.     XtManageChild(toggle_form);
  3062.  
  3063.     if (entry_text != NULL)
  3064.     XmTextFieldSetString(frdp->what, (char *)entry_text);
  3065.     vim_free(entry_text);
  3066.  
  3067.     XtManageChild(frdp->dialog);
  3068.     XmProcessTraversal(frdp->what, XmTRAVERSE_CURRENT);
  3069. }
  3070.  
  3071.    void
  3072. gui_mch_find_dialog(eap)
  3073.     exarg_T    *eap;
  3074. {
  3075.     if (!gui.in_use)
  3076.     return;
  3077.  
  3078.     find_replace_dialog_create(eap->arg, FALSE);
  3079. }
  3080.  
  3081.  
  3082.     void
  3083. gui_mch_replace_dialog(eap)
  3084.     exarg_T    *eap;
  3085. {
  3086.     if (!gui.in_use)
  3087.     return;
  3088.  
  3089.     find_replace_dialog_create(eap->arg, TRUE);
  3090. }
  3091.