[BACK]Return to gui_motif.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

Annotation of src/usr.bin/vim/gui_motif.c, Revision 1.1

1.1     ! downsj      1: /* $OpenBSD$   */
        !             2: /* vi:set ts=4 sw=4:
        !             3:  *
        !             4:  * VIM - Vi IMproved           by Bram Moolenaar
        !             5:  *                             GUI/Motif support by Robert Webb
        !             6:  *
        !             7:  * Do ":help uganda"  in Vim to read copying and usage conditions.
        !             8:  * Do ":help credits" in Vim to see a list of people who contributed.
        !             9:  */
        !            10:
        !            11: #include <Xm/Form.h>
        !            12: #include <Xm/RowColumn.h>
        !            13: #include <Xm/PushB.h>
        !            14: #include <Xm/PanedW.h>
        !            15: #include <Xm/CascadeB.h>
        !            16: #include <Xm/ScrollBar.h>
        !            17: #include <Xm/RowColumn.h>
        !            18: #include <Xm/MenuShell.h>
        !            19: #if (XmVersion >= 1002)
        !            20: # include <Xm/RepType.h>
        !            21: #endif
        !            22:
        !            23: #include <X11/keysym.h>
        !            24: #include <X11/Xatom.h>
        !            25: #include <X11/StringDefs.h>
        !            26:
        !            27: #include "vim.h"
        !            28: #include "globals.h"
        !            29: #include "proto.h"
        !            30: #include "option.h"
        !            31: #include "ops.h"
        !            32:
        !            33: extern Widget vimShell;
        !            34:
        !            35: static Widget vimForm;
        !            36: static Widget textArea;
        !            37: static Widget scrollbarBox[3];     /* Left, right & bottom scrollbar boxes */
        !            38: static Widget menuBar;
        !            39:
        !            40: /*
        !            41:  * Call-back routines.
        !            42:  */
        !            43:
        !            44:    static void
        !            45: scroll_cb(w, client_data, call_data)
        !            46:    Widget      w;
        !            47:    XtPointer   client_data, call_data;
        !            48: {
        !            49:    char_u      bytes[4 + sizeof(long_u)];
        !            50:    WIN         *wp;
        !            51:    GuiScrollbar *sb;
        !            52:    int         sb_num;
        !            53:
        !            54:    if (((XmScrollBarCallbackStruct *)call_data)->reason == XmCR_DRAG)
        !            55:        gui.dragged_sb = (XtParent(w) == scrollbarBox[SB_LEFT]) ? SB_LEFT
        !            56:                                                                : SB_RIGHT;
        !            57:    else
        !            58:        gui.dragged_sb = SB_NONE;
        !            59:    gui.dragged_wp = (WIN *)client_data;
        !            60:    sb_num = 0;
        !            61:    for (wp = firstwin; wp != gui.dragged_wp && wp != NULL; wp = wp->w_next)
        !            62:        sb_num++;
        !            63:
        !            64:    bytes[0] = CSI;
        !            65:    bytes[1] = KS_SCROLLBAR;
        !            66:    bytes[2] = K_FILLER;
        !            67:    bytes[3] = (char_u)sb_num;
        !            68:    if (gui.dragged_wp == NULL)
        !            69:        sb = &gui.cmdline_sb;
        !            70:    else
        !            71:        sb = &wp->w_scrollbar;
        !            72:    sb->value = ((XmScrollBarCallbackStruct *)call_data)->value;
        !            73:    add_long_to_buf((long_u)sb->value, bytes + 4);
        !            74:    add_to_input_buf(bytes, 4 + sizeof(long_u));
        !            75: }
        !            76:
        !            77:    static void
        !            78: horiz_scroll_cb(w, client_data, call_data)
        !            79:    Widget      w;
        !            80:    XtPointer   client_data, call_data;
        !            81: {
        !            82:    char_u      bytes[3 + sizeof(long_u)];
        !            83:
        !            84:    if (((XmScrollBarCallbackStruct *)call_data)->reason == XmCR_DRAG)
        !            85:        gui.dragged_sb = SB_BOTTOM;
        !            86:    else
        !            87:        gui.dragged_sb = SB_NONE;
        !            88:
        !            89:    bytes[0] = CSI;
        !            90:    bytes[1] = KS_HORIZ_SCROLLBAR;
        !            91:    bytes[2] = K_FILLER;
        !            92:    add_long_to_buf((long_u)((XmScrollBarCallbackStruct *)call_data)->value,
        !            93:                    bytes + 3);
        !            94:    add_to_input_buf(bytes, 3 + sizeof(long_u));
        !            95: }
        !            96:
        !            97: /*
        !            98:  * End of call-back routines
        !            99:  */
        !           100:
        !           101: /*
        !           102:  * Create all the motif widgets necessary.
        !           103:  */
        !           104:    void
        !           105: gui_mch_create_widgets()
        !           106: {
        !           107:    int         i;
        !           108:    Dimension   n;
        !           109:
        !           110:    /*
        !           111:     * Start out by adding the configured border width into the border offset
        !           112:     */
        !           113:    gui.border_offset = gui.border_width;
        !           114:
        !           115:    /*
        !           116:     * Install the tearOffModel resource converter.
        !           117:     */
        !           118: #if (XmVersion >= 1002)
        !           119:    XmRepTypeInstallTearOffModelConverter();
        !           120: #endif
        !           121:
        !           122:    XtInitializeWidgetClass(xmFormWidgetClass);
        !           123:    XtInitializeWidgetClass(xmRowColumnWidgetClass);
        !           124:    XtInitializeWidgetClass(xmRowColumnWidgetClass);
        !           125:    XtInitializeWidgetClass(xmPrimitiveWidgetClass);
        !           126:
        !           127:    vimForm = XtVaCreateManagedWidget("vimForm",
        !           128:        xmFormWidgetClass, vimShell,
        !           129:        XmNresizePolicy, XmRESIZE_GROW,
        !           130:         XmNforeground, gui.menu_fg_pixel,
        !           131:         XmNbackground, gui.menu_bg_pixel,
        !           132:        NULL);
        !           133:
        !           134:    menuBar = XtVaCreateManagedWidget("menuBar",
        !           135:        xmRowColumnWidgetClass, vimForm,
        !           136:        XmNresizeHeight, False,
        !           137: #if (XmVersion >= 1002)
        !           138:        XmNtearOffModel, XmTEAR_OFF_ENABLED,
        !           139: #endif
        !           140:        XmNtopAttachment, XmATTACH_FORM,
        !           141:        XmNleftAttachment, XmATTACH_FORM,
        !           142:        XmNrightAttachment, XmATTACH_FORM,
        !           143:        XmNrowColumnType, XmMENU_BAR,
        !           144:        XmNheight, gui.menu_height,
        !           145:         XmNforeground, gui.menu_fg_pixel,
        !           146:         XmNbackground, gui.menu_bg_pixel,
        !           147:        NULL);
        !           148:
        !           149:    scrollbarBox[SB_LEFT] = XtVaCreateWidget("leftScrollBarBox",
        !           150:        xmRowColumnWidgetClass, vimForm,
        !           151:        XmNresizeWidth, False,
        !           152:        XmNtopAttachment, XmATTACH_WIDGET,
        !           153:        XmNtopWidget, menuBar,
        !           154:        XmNbottomAttachment, XmATTACH_FORM,
        !           155:        XmNleftAttachment, XmATTACH_FORM,
        !           156:        XmNmarginWidth, 0,
        !           157:        XmNmarginHeight, 0,
        !           158:        XmNspacing, 0,
        !           159:        XmNwidth, gui.scrollbar_width,
        !           160:        XmNforeground, gui.scroll_fg_pixel,
        !           161:        XmNbackground, gui.scroll_fg_pixel,
        !           162:        NULL);
        !           163:
        !           164:    scrollbarBox[SB_RIGHT] = XtVaCreateWidget("rightScrollBarBox",
        !           165:        xmRowColumnWidgetClass, vimForm,
        !           166:        XmNresizeWidth, False,
        !           167:        XmNtopAttachment, XmATTACH_WIDGET,
        !           168:        XmNtopWidget, menuBar,
        !           169:        XmNbottomAttachment, XmATTACH_FORM,
        !           170:        XmNrightAttachment, XmATTACH_FORM,
        !           171:        XmNmarginWidth, 0,
        !           172:        XmNmarginHeight, 0,
        !           173:        XmNspacing, 0,
        !           174:        XmNwidth, gui.scrollbar_width,
        !           175:        XmNforeground, gui.scroll_fg_pixel,
        !           176:        XmNbackground, gui.scroll_fg_pixel,
        !           177:        NULL);
        !           178:
        !           179:    scrollbarBox[SB_BOTTOM] = XtVaCreateWidget("bottomScrollBarBox",
        !           180:        xmScrollBarWidgetClass, vimForm,
        !           181:        XmNorientation, XmHORIZONTAL,
        !           182:        XmNminimum, 0,
        !           183:        XmNvalue, 0,
        !           184:        XmNsliderSize, Columns,
        !           185:        XmNmaximum, Columns,        /* Motif want one more than actual max */
        !           186:        XmNresizeHeight, False,
        !           187:        XmNbottomAttachment, XmATTACH_FORM,
        !           188:        XmNheight, gui.scrollbar_width,
        !           189:        XmNshadowThickness, 1,
        !           190:        XmNbackground, gui.scroll_fg_pixel,
        !           191:        XmNtroughColor, gui.scroll_bg_pixel,
        !           192:        NULL);
        !           193:    XtAddCallback(scrollbarBox[SB_BOTTOM], XmNvalueChangedCallback,
        !           194:        horiz_scroll_cb, (XtPointer)NULL);
        !           195:    XtAddCallback(scrollbarBox[SB_BOTTOM], XmNdragCallback,
        !           196:        horiz_scroll_cb, (XtPointer)NULL);
        !           197:
        !           198:    textArea = XtVaCreateManagedWidget("textArea",
        !           199:        xmPrimitiveWidgetClass, vimForm,
        !           200:        XmNtopAttachment, XmATTACH_WIDGET,
        !           201:        XmNtopWidget, menuBar,
        !           202:        XmNbackground, gui.back_pixel,
        !           203:
        !           204:        /* These take some control away from the user, but avoids making them
        !           205:         * add resources to get a decent looking setup. */
        !           206:        XmNborderWidth, 0,
        !           207:        XmNhighlightThickness, 0,
        !           208:        XmNshadowThickness, 0,
        !           209:        NULL);
        !           210:
        !           211:    /*
        !           212:     * If there are highlight or shadow borders, add their widths to our
        !           213:     * border offset so we don't draw over them.
        !           214:     */
        !           215:    XtVaGetValues(textArea, XmNhighlightThickness, &n, NULL);
        !           216:    gui.border_offset += n;
        !           217:    XtVaGetValues(textArea, XmNshadowThickness, &n, NULL);
        !           218:    gui.border_offset += n;
        !           219:
        !           220:    /* Create the command line scroll bars */
        !           221:    for (i = 0; i < 2; i++)
        !           222:    {
        !           223:        gui.cmdline_sb.id[i] = XtVaCreateManagedWidget("cmdlineScrollBar",
        !           224:            xmScrollBarWidgetClass, scrollbarBox[i],
        !           225:            XmNshadowThickness, 1,
        !           226:            XmNshowArrows, False,
        !           227:            XmNbackground, gui.scroll_fg_pixel,
        !           228:            XmNtroughColor, gui.scroll_fg_pixel,
        !           229:            NULL);
        !           230:        XtAddCallback(gui.cmdline_sb.id[i], XmNvalueChangedCallback,
        !           231:            scroll_cb, (XtPointer)NULL);
        !           232:        XtAddCallback(gui.cmdline_sb.id[i], XmNdragCallback,
        !           233:            scroll_cb, (XtPointer)NULL);
        !           234:    }
        !           235:    gui.num_scrollbars = 1;
        !           236:
        !           237:    /*
        !           238:     * Text area callbacks
        !           239:     */
        !           240:    XtAddEventHandler(textArea, VisibilityChangeMask, FALSE,
        !           241:        gui_x11_visibility_cb, (XtPointer)0);
        !           242:
        !           243:    XtAddEventHandler(textArea, ExposureMask, FALSE, gui_x11_expose_cb,
        !           244:        (XtPointer)0);
        !           245:
        !           246:    XtAddEventHandler(textArea, StructureNotifyMask, FALSE,
        !           247:        gui_x11_resize_window_cb, (XtPointer)0);
        !           248:
        !           249:    XtAddEventHandler(textArea, FocusChangeMask, FALSE, gui_x11_focus_change_cb,
        !           250:        (XtPointer)0);
        !           251:
        !           252:    XtAddEventHandler(textArea, KeyPressMask, FALSE, gui_x11_key_hit_cb,
        !           253:        (XtPointer)0);
        !           254:
        !           255:    XtAddEventHandler(textArea, ButtonPressMask | ButtonReleaseMask |
        !           256:        ButtonMotionMask, FALSE, gui_x11_mouse_cb, (XtPointer)0);
        !           257: }
        !           258:
        !           259:    int
        !           260: gui_mch_get_winsize()
        !           261: {
        !           262:    Dimension   n;
        !           263:    Dimension   base_width = 0, base_height = 0;
        !           264:
        !           265:    if (gui.which_scrollbars[SB_LEFT])
        !           266:    {
        !           267:        XtVaGetValues(scrollbarBox[SB_LEFT], XmNwidth, &n, NULL);
        !           268:        base_width += n;
        !           269:    }
        !           270:    if (gui.which_scrollbars[SB_RIGHT])
        !           271:    {
        !           272:        XtVaGetValues(scrollbarBox[SB_RIGHT], XmNwidth, &n, NULL);
        !           273:        base_width += n;
        !           274:    }
        !           275:    if (gui.which_scrollbars[SB_BOTTOM])
        !           276:    {
        !           277:        XtVaGetValues(scrollbarBox[SB_BOTTOM], XmNheight, &n, NULL);
        !           278:        base_height += n;
        !           279:    }
        !           280:
        !           281:    base_height += 2 * gui.border_offset;
        !           282:    base_width  += 2 * gui.border_offset;
        !           283:
        !           284:    if (gui.menu_is_active)
        !           285:    {
        !           286:        XtVaGetValues(menuBar, XmNheight, &n, NULL);
        !           287:        base_height += n;
        !           288:    }
        !           289:
        !           290:    XtVaGetValues(vimShell, XmNheight, &n, NULL);
        !           291:    gui.num_rows = (int)(n - base_height) / (int)gui.char_height;
        !           292:
        !           293:    XtVaGetValues(vimShell, XmNwidth, &n, NULL);
        !           294:    gui.num_cols = (int)(n - base_width) / (int)gui.char_width;
        !           295:
        !           296:    Rows = gui.num_rows;
        !           297:    Columns = gui.num_cols;
        !           298:    gui_reset_scroll_region();
        !           299:
        !           300:    return OK;
        !           301: }
        !           302:
        !           303:    void
        !           304: gui_mch_set_winsize()
        !           305: {
        !           306:    Dimension   left_width, right_width, bottom_height, menu_height;
        !           307:    Dimension   base_width = 0, base_height = 0;
        !           308:
        !           309:    base_width  += 2 * gui.border_offset;
        !           310:    base_height += 2 * gui.border_offset;
        !           311:
        !           312:    if (gui.which_scrollbars[SB_LEFT])
        !           313:    {
        !           314:        XtVaGetValues(scrollbarBox[SB_LEFT], XmNwidth, &left_width, NULL);
        !           315:        base_width += left_width;
        !           316:    }
        !           317:    if (gui.which_scrollbars[SB_RIGHT])
        !           318:    {
        !           319:        XtVaGetValues(scrollbarBox[SB_RIGHT], XmNwidth, &right_width, NULL);
        !           320:        base_width += right_width;
        !           321:    }
        !           322:    if (gui.which_scrollbars[SB_BOTTOM])
        !           323:    {
        !           324:        XtVaGetValues(scrollbarBox[SB_BOTTOM], XmNheight, &bottom_height, NULL);
        !           325:        base_height += bottom_height;
        !           326:    }
        !           327:    if (gui.menu_is_active)
        !           328:    {
        !           329:        XtVaGetValues(menuBar, XmNheight, &menu_height, NULL);
        !           330:        base_height += menu_height;
        !           331:    }
        !           332:
        !           333:    XtVaSetValues(vimShell,
        !           334: #ifdef XmNbaseWidth
        !           335:        XmNbaseWidth, base_width,
        !           336:        XmNbaseHeight, base_height,
        !           337: #endif
        !           338:        XmNwidthInc,  gui.char_width,
        !           339:        XmNheightInc, gui.char_height,
        !           340:        XmNminWidth,  base_width  + MIN_COLUMNS * gui.char_width,
        !           341:        XmNminHeight, base_height + MIN_ROWS * gui.char_height,
        !           342:        XmNwidth,     base_width  + Columns * gui.char_width,
        !           343:        XmNheight,    base_height + Rows * gui.char_height,
        !           344:        NULL);
        !           345: }
        !           346:
        !           347: /*
        !           348:  * Menu stuff.
        !           349:  */
        !           350:
        !           351:    void
        !           352: gui_mch_add_menu(menu, parent)
        !           353:    GuiMenu *menu;
        !           354:    GuiMenu *parent;
        !           355: {
        !           356: #if (XmVersion >= 1002)
        !           357:    Widget      widget;
        !           358:    XmString label = XmStringCreate((char *)menu->name,
        !           359:                                                      XmFONTLIST_DEFAULT_TAG);
        !           360: #else
        !           361:    XmString label = XmStringCreate((char *)menu->name,
        !           362:                                                    XmSTRING_DEFAULT_CHARSET);
        !           363: #endif
        !           364:    Widget shell;
        !           365:
        !           366:    menu->id = XtVaCreateWidget("subMenu",
        !           367:        xmCascadeButtonWidgetClass,
        !           368:        (parent == NULL) ? menuBar : parent->submenu_id,
        !           369:        XmNlabelString, label,
        !           370:         XmNforeground, gui.menu_fg_pixel,
        !           371:         XmNbackground, gui.menu_bg_pixel,
        !           372:        NULL);
        !           373:    /* XtFree((char *)label); makes Lesstif crash */
        !           374:
        !           375:    /* if 'guic' contains 'g', make menu's contain grey items */
        !           376:    if (vim_strchr(p_guioptions, GO_GREY) != NULL)
        !           377:        XtManageChild(menu->id);
        !           378:
        !           379:    shell = XtVaCreateWidget("subMenuShell",
        !           380:        xmMenuShellWidgetClass, menu->id,
        !           381:        XmNwidth, 1,
        !           382:        XmNheight, 1,
        !           383:         XmNforeground, gui.menu_fg_pixel,
        !           384:         XmNbackground, gui.menu_bg_pixel,
        !           385:        NULL);
        !           386:    menu->submenu_id = XtVaCreateWidget("rowColumnMenu",
        !           387:        xmRowColumnWidgetClass, shell,
        !           388:        XmNrowColumnType, XmMENU_PULLDOWN,
        !           389: #if (XmVersion >= 1002)
        !           390:        XmNtearOffModel, XmTEAR_OFF_ENABLED,
        !           391: #endif
        !           392:        NULL);
        !           393:
        !           394: #if (XmVersion >= 1002)
        !           395:    /* Set the colors for the tear off widget */
        !           396:    if ((widget = XmGetTearOffControl(menu->submenu_id)) != (Widget)NULL)
        !           397:        XtVaSetValues(widget,
        !           398:            XmNforeground, gui.menu_fg_pixel,
        !           399:            XmNbackground, gui.menu_bg_pixel,
        !           400:            NULL);
        !           401: #endif
        !           402:
        !           403:    XtVaSetValues(menu->id,
        !           404:        XmNsubMenuId, menu->submenu_id,
        !           405:        NULL);
        !           406:
        !           407:    /*
        !           408:     * The "Help" menu is a special case, and should be placed at the far right
        !           409:     * hand side of the menu-bar.
        !           410:     */
        !           411:    if (parent == NULL && STRCMP((char *)menu->name, "Help") == 0)
        !           412:        XtVaSetValues(menuBar,
        !           413:            XmNmenuHelpWidget, menu->id,
        !           414:            NULL);
        !           415:
        !           416:     if (parent == NULL)
        !           417:        XtVaSetValues(XtParent(menu->id),
        !           418:             XmNforeground, gui.menu_fg_pixel,
        !           419:             XmNbackground, gui.menu_bg_pixel,
        !           420:             NULL);
        !           421: }
        !           422:
        !           423:    void
        !           424: gui_mch_add_menu_item(menu, parent)
        !           425:    GuiMenu *menu;
        !           426:    GuiMenu *parent;
        !           427: {
        !           428: #if (XmVersion >= 1002)
        !           429:    XmString label = XmStringCreate((char *)menu->name,
        !           430:                                                      XmFONTLIST_DEFAULT_TAG);
        !           431: #else
        !           432:    XmString label = XmStringCreate((char *)menu->name,
        !           433:                                                    XmSTRING_DEFAULT_CHARSET);
        !           434: #endif
        !           435:
        !           436:    menu->submenu_id = (Widget)0;
        !           437:    menu->id = XtVaCreateWidget("subMenu",
        !           438:        xmPushButtonWidgetClass, parent->submenu_id,
        !           439:        XmNlabelString, label,
        !           440:         XmNforeground, gui.menu_fg_pixel,
        !           441:         XmNbackground, gui.menu_bg_pixel,
        !           442:        NULL);
        !           443:    /* XtFree((char *)label); makes Lesstif crash */
        !           444:
        !           445:    if (vim_strchr(p_guioptions, GO_GREY) != NULL)
        !           446:        XtManageChild(menu->id);
        !           447:
        !           448:    XtAddCallback(menu->id, XmNactivateCallback, gui_x11_menu_cb,
        !           449:        (XtPointer)menu);
        !           450: }
        !           451:
        !           452: /*
        !           453:  * Destroy the machine specific menu widget.
        !           454:  */
        !           455:    void
        !           456: gui_mch_destroy_menu(menu)
        !           457:    GuiMenu *menu;
        !           458: {
        !           459:    if (menu->id != (Widget)0)
        !           460:        XtDestroyWidget(menu->id);
        !           461:    if (menu->submenu_id != (Widget)0)
        !           462:        XtDestroyWidget(menu->submenu_id);
        !           463: }
        !           464:
        !           465: /*
        !           466:  * Scrollbar stuff:
        !           467:  */
        !           468:
        !           469:    void
        !           470: gui_mch_create_which_components()
        !           471: {
        !           472:    static int prev_which_scrollbars[3] = {FALSE, FALSE, FALSE};
        !           473:
        !           474:    int     i;
        !           475:    char    *attach = NULL, *widget = NULL;     /* NOT char_u */
        !           476:    WIN     *wp;
        !           477:
        !           478:    gui_x11_use_resize_callback(textArea, FALSE);
        !           479:
        !           480:    for (i = 0; i < 3; i++)
        !           481:    {
        !           482:        switch (i)
        !           483:        {
        !           484:            case SB_LEFT:   attach = XmNleftAttachment;
        !           485:                            widget = XmNleftWidget;         break;
        !           486:            case SB_RIGHT:  attach = XmNrightAttachment;
        !           487:                            widget = XmNrightWidget;        break;
        !           488:            case SB_BOTTOM: attach = XmNbottomAttachment;
        !           489:                            widget = XmNbottomWidget;       break;
        !           490:        }
        !           491:        if (gui.which_scrollbars[i])
        !           492:        {
        !           493:            XtManageChild(scrollbarBox[i]);
        !           494:            XtVaSetValues(textArea,
        !           495:                attach, XmATTACH_WIDGET,
        !           496:                widget, scrollbarBox[i],
        !           497:                NULL);
        !           498:            if (i != SB_BOTTOM && gui.which_scrollbars[SB_BOTTOM])
        !           499:                XtVaSetValues(scrollbarBox[SB_BOTTOM],
        !           500:                    attach, XmATTACH_WIDGET,
        !           501:                    widget, scrollbarBox[i],
        !           502:                    NULL);
        !           503:        }
        !           504:        else
        !           505:        {
        !           506:            XtUnmanageChild(scrollbarBox[i]);
        !           507:            XtVaSetValues(textArea,
        !           508:                attach, XmATTACH_FORM,
        !           509:                NULL);
        !           510:            if (i != SB_BOTTOM && gui.which_scrollbars[SB_BOTTOM])
        !           511:                XtVaSetValues(scrollbarBox[SB_BOTTOM],
        !           512:                    attach, XmATTACH_FORM,
        !           513:                    NULL);
        !           514:        }
        !           515:        if (gui.which_scrollbars[i] != prev_which_scrollbars[i])
        !           516:        {
        !           517:            if (i == SB_LEFT || i == SB_RIGHT)
        !           518:            {
        !           519:                if (gui.which_scrollbars[i])
        !           520:                {
        !           521:                    /* Scrollbar box has just appeared */
        !           522:                    gui.new_sb[i] = TRUE;
        !           523:                }
        !           524:                else
        !           525:                {
        !           526:                    /* Scrollbar box has just been deleted */
        !           527:                    for (wp = firstwin; wp != NULL; wp = wp->w_next)
        !           528:                        XtDestroyWidget(wp->w_scrollbar.id[i]);
        !           529:                }
        !           530:            }
        !           531:            prev_which_scrollbars[i] = gui.which_scrollbars[i];
        !           532:        }
        !           533:    }
        !           534:    if (gui.menu_is_active)
        !           535:    {
        !           536:        XtManageChild(menuBar);
        !           537:        XtVaSetValues(textArea, XmNtopAttachment, XmATTACH_WIDGET,
        !           538:                        XmNtopWidget, menuBar, NULL);
        !           539:        if (gui.which_scrollbars[SB_LEFT])
        !           540:        {
        !           541:            XtVaSetValues(scrollbarBox[SB_LEFT],
        !           542:                XmNtopAttachment, XmATTACH_WIDGET,
        !           543:                XmNtopWidget, menuBar,
        !           544:                NULL);
        !           545:        }
        !           546:        if (gui.which_scrollbars[SB_RIGHT])
        !           547:        {
        !           548:            XtVaSetValues(scrollbarBox[SB_RIGHT],
        !           549:                XmNtopAttachment, XmATTACH_WIDGET,
        !           550:                XmNtopWidget, menuBar,
        !           551:                NULL);
        !           552:        }
        !           553:    }
        !           554:     else
        !           555:    {
        !           556:        XtUnmanageChild(menuBar);
        !           557:        XtVaSetValues(textArea, XmNtopAttachment, XmATTACH_FORM, NULL);
        !           558:        if (gui.which_scrollbars[SB_LEFT])
        !           559:        {
        !           560:            XtVaSetValues(scrollbarBox[SB_LEFT],
        !           561:                XmNtopAttachment, XmATTACH_FORM, NULL);
        !           562:        }
        !           563:        if (gui.which_scrollbars[SB_RIGHT])
        !           564:        {
        !           565:            XtVaSetValues(scrollbarBox[SB_RIGHT],
        !           566:                XmNtopAttachment, XmATTACH_FORM, NULL);
        !           567:        }
        !           568:    }
        !           569:    gui_x11_use_resize_callback(textArea, TRUE);
        !           570:    if (vimForm != (Widget)NULL)
        !           571:        gui_mch_set_winsize();
        !           572: }
        !           573:
        !           574:
        !           575: /*
        !           576:  * Vertical scrollbar stuff:
        !           577:  */
        !           578:
        !           579:    void
        !           580: gui_mch_update_scrollbars(worst_update, which_sb)
        !           581:    int     worst_update;
        !           582:    int     which_sb;       /* SB_LEFT or SB_RIGHT */
        !           583: {
        !           584:    WIN             *wp;
        !           585:    GuiScrollbar    *sb;
        !           586:    int             idx;
        !           587:    Dimension       h;      /* Height of scrollbar (in pixels) */
        !           588:    Dimension       y;      /* Coord of top of scrollbar (in pixels) */
        !           589:    int             tmp;
        !           590:    int             val = 0, size = 0, max = 0;
        !           591:
        !           592:    if (worst_update >= SB_UPDATE_HEIGHT)
        !           593:    {
        !           594:        gui_x11_use_resize_callback(textArea, FALSE);
        !           595:        XtUnmanageChild(scrollbarBox[which_sb]);
        !           596:    }
        !           597:
        !           598:    for (wp = firstwin, idx = 0; wp; wp = wp->w_next, idx++)
        !           599:    {
        !           600:        sb = &wp->w_scrollbar;
        !           601:        if (sb->update[which_sb] >= SB_UPDATE_VALUE)
        !           602:        {
        !           603:            val = sb->value;
        !           604:            size = sb->size;
        !           605:            max = sb->max + 1;      /* Motif has max one past the end */
        !           606:        }
        !           607:        if (sb->update[which_sb] == SB_UPDATE_CREATE)
        !           608:        {
        !           609:            sb->id[which_sb] = XtVaCreateManagedWidget("scrollBar",
        !           610:                xmScrollBarWidgetClass, scrollbarBox[which_sb],
        !           611:                XmNshadowThickness, 1,
        !           612: #if (XmVersion >= 1002)        /* What do we do otherwise? */
        !           613:                XmNpositionIndex, idx,
        !           614: #endif
        !           615:                XmNminimum, 1,
        !           616:                XmNmaximum, max,
        !           617:                XmNbackground, gui.scroll_fg_pixel,
        !           618:                XmNtroughColor, gui.scroll_bg_pixel,
        !           619:                NULL);
        !           620:            XtAddCallback(sb->id[which_sb], XmNvalueChangedCallback,
        !           621:                scroll_cb, (XtPointer)wp);
        !           622:            XtAddCallback(sb->id[which_sb], XmNdragCallback,
        !           623:                scroll_cb, (XtPointer)wp);
        !           624:        }
        !           625:        if (sb->update[which_sb] >= SB_UPDATE_HEIGHT)
        !           626:        {
        !           627:            h = sb->height * gui.char_height
        !           628:                    + sb->status_height * gui.char_height / 2;
        !           629:            y = wp->w_winpos * gui.char_height;
        !           630:
        !           631:            if (wp == firstwin)
        !           632:            {
        !           633:                /* Height of top scrollbar includes width of top border */
        !           634:                h += gui.border_offset;
        !           635:            }
        !           636:            else
        !           637:            {
        !           638:                /*
        !           639:                 * Height of other scrollbars includes half of status bar above
        !           640:                 */
        !           641:                tmp = wp->w_prev->w_status_height * (gui.char_height + 1) / 2;
        !           642:                h += tmp;
        !           643:                y += gui.border_offset - tmp;
        !           644:            }
        !           645:
        !           646:            XtVaSetValues(sb->id[which_sb],
        !           647:                XmNvalue, val,
        !           648:                XmNsliderSize, size,
        !           649:                XmNpageIncrement, (size > 2 ? size - 2 : 1),
        !           650:                XmNmaximum, max,
        !           651:                XmNheight, h,
        !           652:                XmNy, y,
        !           653:                NULL);
        !           654:        }
        !           655:        else if (sb->update[which_sb] == SB_UPDATE_VALUE)
        !           656:        {
        !           657:            XtVaSetValues(sb->id[which_sb],
        !           658:                XmNvalue, val,
        !           659:                XmNsliderSize, size,
        !           660:                XmNpageIncrement, (size > 2 ? size - 2 : 1),
        !           661:                XmNmaximum, max,
        !           662:                NULL);
        !           663:        }
        !           664:        sb->update[which_sb] = SB_UPDATE_NOTHING;
        !           665:    }
        !           666:
        !           667:    /* Command line scrollbar */
        !           668:    sb = &gui.cmdline_sb;
        !           669:    max = sb->max + 1;          /* Motif has max one past the end */
        !           670:    if (sb->update[which_sb] == SB_UPDATE_HEIGHT)
        !           671:    {
        !           672:        h = lastwin->w_status_height * (gui.char_height + 1) / 2;
        !           673:        y = (Rows - sb->height) * gui.char_height - h;
        !           674:        h += sb->height * gui.char_height;
        !           675:
        !           676:        /* Height of cmdline scrollbar includes width of bottom border */
        !           677:        h += gui.border_offset;
        !           678:
        !           679:        XtVaSetValues(sb->id[which_sb],
        !           680:            XmNvalue, sb->value,
        !           681:            XmNsliderSize, sb->size,
        !           682:            XmNmaximum, max,
        !           683:            XmNheight, h,
        !           684:            XmNy, y,
        !           685:            NULL);
        !           686:    }
        !           687:    else if (sb->update[which_sb] == SB_UPDATE_VALUE)
        !           688:    {
        !           689:        XtVaSetValues(sb->id[which_sb],
        !           690:            XmNvalue, sb->value,
        !           691:            XmNsliderSize, sb->size,
        !           692:            XmNmaximum, max,
        !           693:            NULL);
        !           694:    }
        !           695:    sb->update[which_sb] = SB_UPDATE_NOTHING;
        !           696:
        !           697:    if (worst_update >= SB_UPDATE_HEIGHT)
        !           698:    {
        !           699:        if (worst_update >= SB_UPDATE_CREATE)
        !           700:            gui_mch_reorder_scrollbars(which_sb);
        !           701:        XtManageChild(scrollbarBox[which_sb]);
        !           702:        gui_x11_use_resize_callback(textArea, TRUE);
        !           703:    }
        !           704: }
        !           705:
        !           706:    void
        !           707: gui_mch_reorder_scrollbars(which_sb)
        !           708:    int     which_sb;
        !           709: {
        !           710:    Widget *children;
        !           711:    int     num_children;
        !           712:    Widget  tmp;
        !           713:    WIN     *wp, *wp2;
        !           714:    int     i, j;
        !           715:
        !           716:    XtVaGetValues(scrollbarBox[which_sb],
        !           717:        XmNchildren, &children,
        !           718:        XmNnumChildren, &num_children,
        !           719:        NULL);
        !           720:
        !           721:    /* Should be in same order as in the window list */
        !           722:    wp = firstwin;
        !           723:    for (i = 0; i < num_children; i++, wp = wp->w_next)
        !           724:    {
        !           725:        if (wp == NULL)
        !           726:            break;      /* Shouldn't happen */
        !           727:        if (wp->w_scrollbar.id[which_sb] != children[i])
        !           728:        {
        !           729:            /* It's in the wrong place, find what should go here */
        !           730:            wp2 = wp->w_next;
        !           731:            for (j = i + 1; j < num_children; j++, wp2 = wp2->w_next)
        !           732:            {
        !           733:                if (wp2 == NULL)
        !           734:                    break;      /* Shouldn't happen */
        !           735:                if (wp->w_scrollbar.id[which_sb] == children[j])
        !           736:                    break;      /* Found it */
        !           737:            }
        !           738:            if (j >= num_children || wp2 == NULL)
        !           739:                break;          /* Shouldn't happen */
        !           740:            tmp = children[i];
        !           741:            children[i] = children[j];
        !           742:            children[j] = tmp;
        !           743:        }
        !           744:    }
        !           745:
        !           746:    XtVaSetValues(scrollbarBox[which_sb],
        !           747:        XmNchildren, children,
        !           748:        NULL);
        !           749: }
        !           750:
        !           751:    void
        !           752: gui_mch_destroy_scrollbar(wp)
        !           753:    WIN     *wp;
        !           754: {
        !           755:    if (gui.which_scrollbars[SB_LEFT])
        !           756:        XtDestroyWidget(wp->w_scrollbar.id[SB_LEFT]);
        !           757:    if (gui.which_scrollbars[SB_RIGHT])
        !           758:        XtDestroyWidget(wp->w_scrollbar.id[SB_RIGHT]);
        !           759:    gui.num_scrollbars--;
        !           760: }
        !           761:
        !           762:
        !           763: /*
        !           764:  * Horizontal scrollbar stuff:
        !           765:  */
        !           766:
        !           767:    void
        !           768: gui_mch_update_horiz_scrollbar(value, size, max)
        !           769:    int     value;
        !           770:    int     size;
        !           771:    int     max;
        !           772: {
        !           773:    static int prev_value = -1, prev_size = -1, prev_max = -1;
        !           774:
        !           775:    if (value == prev_value && size == prev_size && max == prev_max)
        !           776:        return;
        !           777:
        !           778:    prev_value = value;
        !           779:    prev_size = size;
        !           780:    prev_max = max;
        !           781:
        !           782:    XtVaSetValues(scrollbarBox[SB_BOTTOM],
        !           783:        XmNvalue, value,
        !           784:        XmNsliderSize, size,
        !           785:        XmNpageIncrement, (size > 2 ? size - 2 : 1),
        !           786:        XmNmaximum, max,
        !           787:        NULL);
        !           788: }
        !           789:
        !           790:    Window
        !           791: gui_mch_get_wid()
        !           792: {
        !           793:    return( XtWindow(textArea) );
        !           794: }