[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.2

1.2     ! downsj      1: /* $OpenBSD: gui_motif.c,v 1.1.1.1 1996/09/07 21:40:28 downsj Exp $    */
1.1       downsj      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:
1.2     ! downsj    333:    /*
        !           334:     * Need to unmanage vimForm here for a moment, to avoid an error message
        !           335:     * when .gvimrc contains ":set guioptions=r".
        !           336:     */
        !           337:    XtUnmanageChild(vimForm);
1.1       downsj    338:    XtVaSetValues(vimShell,
                    339: #ifdef XmNbaseWidth
                    340:        XmNbaseWidth, base_width,
                    341:        XmNbaseHeight, base_height,
                    342: #endif
                    343:        XmNwidthInc,  gui.char_width,
                    344:        XmNheightInc, gui.char_height,
                    345:        XmNminWidth,  base_width  + MIN_COLUMNS * gui.char_width,
                    346:        XmNminHeight, base_height + MIN_ROWS * gui.char_height,
                    347:        XmNwidth,     base_width  + Columns * gui.char_width,
                    348:        XmNheight,    base_height + Rows * gui.char_height,
                    349:        NULL);
1.2     ! downsj    350:    XtManageChild(vimForm);
1.1       downsj    351: }
                    352:
                    353: /*
                    354:  * Menu stuff.
                    355:  */
                    356:
                    357:    void
                    358: gui_mch_add_menu(menu, parent)
                    359:    GuiMenu *menu;
                    360:    GuiMenu *parent;
                    361: {
                    362: #if (XmVersion >= 1002)
                    363:    Widget      widget;
                    364:    XmString label = XmStringCreate((char *)menu->name,
                    365:                                                      XmFONTLIST_DEFAULT_TAG);
                    366: #else
                    367:    XmString label = XmStringCreate((char *)menu->name,
                    368:                                                    XmSTRING_DEFAULT_CHARSET);
                    369: #endif
                    370:    Widget shell;
                    371:
                    372:    menu->id = XtVaCreateWidget("subMenu",
                    373:        xmCascadeButtonWidgetClass,
                    374:        (parent == NULL) ? menuBar : parent->submenu_id,
                    375:        XmNlabelString, label,
                    376:         XmNforeground, gui.menu_fg_pixel,
                    377:         XmNbackground, gui.menu_bg_pixel,
                    378:        NULL);
                    379:    /* XtFree((char *)label); makes Lesstif crash */
                    380:
                    381:    /* if 'guic' contains 'g', make menu's contain grey items */
                    382:    if (vim_strchr(p_guioptions, GO_GREY) != NULL)
                    383:        XtManageChild(menu->id);
                    384:
                    385:    shell = XtVaCreateWidget("subMenuShell",
                    386:        xmMenuShellWidgetClass, menu->id,
                    387:        XmNwidth, 1,
                    388:        XmNheight, 1,
                    389:         XmNforeground, gui.menu_fg_pixel,
                    390:         XmNbackground, gui.menu_bg_pixel,
                    391:        NULL);
                    392:    menu->submenu_id = XtVaCreateWidget("rowColumnMenu",
                    393:        xmRowColumnWidgetClass, shell,
                    394:        XmNrowColumnType, XmMENU_PULLDOWN,
                    395: #if (XmVersion >= 1002)
                    396:        XmNtearOffModel, XmTEAR_OFF_ENABLED,
                    397: #endif
                    398:        NULL);
                    399:
                    400: #if (XmVersion >= 1002)
                    401:    /* Set the colors for the tear off widget */
                    402:    if ((widget = XmGetTearOffControl(menu->submenu_id)) != (Widget)NULL)
                    403:        XtVaSetValues(widget,
                    404:            XmNforeground, gui.menu_fg_pixel,
                    405:            XmNbackground, gui.menu_bg_pixel,
                    406:            NULL);
                    407: #endif
                    408:
                    409:    XtVaSetValues(menu->id,
                    410:        XmNsubMenuId, menu->submenu_id,
                    411:        NULL);
                    412:
                    413:    /*
                    414:     * The "Help" menu is a special case, and should be placed at the far right
                    415:     * hand side of the menu-bar.
                    416:     */
                    417:    if (parent == NULL && STRCMP((char *)menu->name, "Help") == 0)
                    418:        XtVaSetValues(menuBar,
                    419:            XmNmenuHelpWidget, menu->id,
                    420:            NULL);
                    421:
                    422:     if (parent == NULL)
                    423:        XtVaSetValues(XtParent(menu->id),
                    424:             XmNforeground, gui.menu_fg_pixel,
                    425:             XmNbackground, gui.menu_bg_pixel,
                    426:             NULL);
                    427: }
                    428:
                    429:    void
                    430: gui_mch_add_menu_item(menu, parent)
                    431:    GuiMenu *menu;
                    432:    GuiMenu *parent;
                    433: {
                    434: #if (XmVersion >= 1002)
                    435:    XmString label = XmStringCreate((char *)menu->name,
                    436:                                                      XmFONTLIST_DEFAULT_TAG);
                    437: #else
                    438:    XmString label = XmStringCreate((char *)menu->name,
                    439:                                                    XmSTRING_DEFAULT_CHARSET);
                    440: #endif
                    441:
                    442:    menu->submenu_id = (Widget)0;
                    443:    menu->id = XtVaCreateWidget("subMenu",
                    444:        xmPushButtonWidgetClass, parent->submenu_id,
                    445:        XmNlabelString, label,
                    446:         XmNforeground, gui.menu_fg_pixel,
                    447:         XmNbackground, gui.menu_bg_pixel,
                    448:        NULL);
                    449:    /* XtFree((char *)label); makes Lesstif crash */
                    450:
                    451:    if (vim_strchr(p_guioptions, GO_GREY) != NULL)
                    452:        XtManageChild(menu->id);
                    453:
                    454:    XtAddCallback(menu->id, XmNactivateCallback, gui_x11_menu_cb,
                    455:        (XtPointer)menu);
                    456: }
                    457:
                    458: /*
                    459:  * Destroy the machine specific menu widget.
                    460:  */
                    461:    void
                    462: gui_mch_destroy_menu(menu)
                    463:    GuiMenu *menu;
                    464: {
                    465:    if (menu->id != (Widget)0)
                    466:        XtDestroyWidget(menu->id);
                    467:    if (menu->submenu_id != (Widget)0)
                    468:        XtDestroyWidget(menu->submenu_id);
                    469: }
                    470:
                    471: /*
                    472:  * Scrollbar stuff:
                    473:  */
                    474:
                    475:    void
                    476: gui_mch_create_which_components()
                    477: {
                    478:    static int prev_which_scrollbars[3] = {FALSE, FALSE, FALSE};
                    479:
                    480:    int     i;
                    481:    char    *attach = NULL, *widget = NULL;     /* NOT char_u */
                    482:    WIN     *wp;
                    483:
                    484:    gui_x11_use_resize_callback(textArea, FALSE);
                    485:
                    486:    for (i = 0; i < 3; i++)
                    487:    {
                    488:        switch (i)
                    489:        {
                    490:            case SB_LEFT:   attach = XmNleftAttachment;
                    491:                            widget = XmNleftWidget;         break;
                    492:            case SB_RIGHT:  attach = XmNrightAttachment;
                    493:                            widget = XmNrightWidget;        break;
                    494:            case SB_BOTTOM: attach = XmNbottomAttachment;
                    495:                            widget = XmNbottomWidget;       break;
                    496:        }
                    497:        if (gui.which_scrollbars[i])
                    498:        {
                    499:            XtManageChild(scrollbarBox[i]);
                    500:            XtVaSetValues(textArea,
                    501:                attach, XmATTACH_WIDGET,
                    502:                widget, scrollbarBox[i],
                    503:                NULL);
                    504:            if (i != SB_BOTTOM && gui.which_scrollbars[SB_BOTTOM])
                    505:                XtVaSetValues(scrollbarBox[SB_BOTTOM],
                    506:                    attach, XmATTACH_WIDGET,
                    507:                    widget, scrollbarBox[i],
                    508:                    NULL);
                    509:        }
                    510:        else
                    511:        {
                    512:            XtUnmanageChild(scrollbarBox[i]);
                    513:            XtVaSetValues(textArea,
                    514:                attach, XmATTACH_FORM,
                    515:                NULL);
                    516:            if (i != SB_BOTTOM && gui.which_scrollbars[SB_BOTTOM])
                    517:                XtVaSetValues(scrollbarBox[SB_BOTTOM],
                    518:                    attach, XmATTACH_FORM,
                    519:                    NULL);
                    520:        }
                    521:        if (gui.which_scrollbars[i] != prev_which_scrollbars[i])
                    522:        {
                    523:            if (i == SB_LEFT || i == SB_RIGHT)
                    524:            {
                    525:                if (gui.which_scrollbars[i])
                    526:                {
                    527:                    /* Scrollbar box has just appeared */
                    528:                    gui.new_sb[i] = TRUE;
                    529:                }
                    530:                else
                    531:                {
                    532:                    /* Scrollbar box has just been deleted */
                    533:                    for (wp = firstwin; wp != NULL; wp = wp->w_next)
                    534:                        XtDestroyWidget(wp->w_scrollbar.id[i]);
                    535:                }
                    536:            }
                    537:            prev_which_scrollbars[i] = gui.which_scrollbars[i];
                    538:        }
                    539:    }
                    540:    if (gui.menu_is_active)
                    541:    {
                    542:        XtManageChild(menuBar);
                    543:        XtVaSetValues(textArea, XmNtopAttachment, XmATTACH_WIDGET,
                    544:                        XmNtopWidget, menuBar, NULL);
                    545:        if (gui.which_scrollbars[SB_LEFT])
                    546:        {
                    547:            XtVaSetValues(scrollbarBox[SB_LEFT],
                    548:                XmNtopAttachment, XmATTACH_WIDGET,
                    549:                XmNtopWidget, menuBar,
                    550:                NULL);
                    551:        }
                    552:        if (gui.which_scrollbars[SB_RIGHT])
                    553:        {
                    554:            XtVaSetValues(scrollbarBox[SB_RIGHT],
                    555:                XmNtopAttachment, XmATTACH_WIDGET,
                    556:                XmNtopWidget, menuBar,
                    557:                NULL);
                    558:        }
                    559:    }
                    560:     else
                    561:    {
                    562:        XtUnmanageChild(menuBar);
                    563:        XtVaSetValues(textArea, XmNtopAttachment, XmATTACH_FORM, NULL);
                    564:        if (gui.which_scrollbars[SB_LEFT])
                    565:        {
                    566:            XtVaSetValues(scrollbarBox[SB_LEFT],
                    567:                XmNtopAttachment, XmATTACH_FORM, NULL);
                    568:        }
                    569:        if (gui.which_scrollbars[SB_RIGHT])
                    570:        {
                    571:            XtVaSetValues(scrollbarBox[SB_RIGHT],
                    572:                XmNtopAttachment, XmATTACH_FORM, NULL);
                    573:        }
                    574:    }
                    575:    gui_x11_use_resize_callback(textArea, TRUE);
                    576:    if (vimForm != (Widget)NULL)
                    577:        gui_mch_set_winsize();
                    578: }
                    579:
                    580:
                    581: /*
                    582:  * Vertical scrollbar stuff:
                    583:  */
                    584:
                    585:    void
                    586: gui_mch_update_scrollbars(worst_update, which_sb)
                    587:    int     worst_update;
                    588:    int     which_sb;       /* SB_LEFT or SB_RIGHT */
                    589: {
                    590:    WIN             *wp;
                    591:    GuiScrollbar    *sb;
                    592:    int             idx;
                    593:    Dimension       h;      /* Height of scrollbar (in pixels) */
                    594:    Dimension       y;      /* Coord of top of scrollbar (in pixels) */
                    595:    int             tmp;
                    596:    int             val = 0, size = 0, max = 0;
                    597:
                    598:    if (worst_update >= SB_UPDATE_HEIGHT)
                    599:    {
                    600:        gui_x11_use_resize_callback(textArea, FALSE);
                    601:        XtUnmanageChild(scrollbarBox[which_sb]);
                    602:    }
                    603:
                    604:    for (wp = firstwin, idx = 0; wp; wp = wp->w_next, idx++)
                    605:    {
                    606:        sb = &wp->w_scrollbar;
                    607:        if (sb->update[which_sb] >= SB_UPDATE_VALUE)
                    608:        {
                    609:            val = sb->value;
                    610:            size = sb->size;
                    611:            max = sb->max + 1;      /* Motif has max one past the end */
                    612:        }
                    613:        if (sb->update[which_sb] == SB_UPDATE_CREATE)
                    614:        {
                    615:            sb->id[which_sb] = XtVaCreateManagedWidget("scrollBar",
                    616:                xmScrollBarWidgetClass, scrollbarBox[which_sb],
                    617:                XmNshadowThickness, 1,
                    618: #if (XmVersion >= 1002)        /* What do we do otherwise? */
                    619:                XmNpositionIndex, idx,
                    620: #endif
                    621:                XmNminimum, 1,
                    622:                XmNmaximum, max,
                    623:                XmNbackground, gui.scroll_fg_pixel,
                    624:                XmNtroughColor, gui.scroll_bg_pixel,
                    625:                NULL);
                    626:            XtAddCallback(sb->id[which_sb], XmNvalueChangedCallback,
                    627:                scroll_cb, (XtPointer)wp);
                    628:            XtAddCallback(sb->id[which_sb], XmNdragCallback,
                    629:                scroll_cb, (XtPointer)wp);
                    630:        }
                    631:        if (sb->update[which_sb] >= SB_UPDATE_HEIGHT)
                    632:        {
                    633:            h = sb->height * gui.char_height
                    634:                    + sb->status_height * gui.char_height / 2;
                    635:            y = wp->w_winpos * gui.char_height;
                    636:
                    637:            if (wp == firstwin)
                    638:            {
                    639:                /* Height of top scrollbar includes width of top border */
                    640:                h += gui.border_offset;
                    641:            }
                    642:            else
                    643:            {
                    644:                /*
                    645:                 * Height of other scrollbars includes half of status bar above
                    646:                 */
                    647:                tmp = wp->w_prev->w_status_height * (gui.char_height + 1) / 2;
                    648:                h += tmp;
                    649:                y += gui.border_offset - tmp;
                    650:            }
                    651:
                    652:            XtVaSetValues(sb->id[which_sb],
                    653:                XmNvalue, val,
                    654:                XmNsliderSize, size,
                    655:                XmNpageIncrement, (size > 2 ? size - 2 : 1),
                    656:                XmNmaximum, max,
                    657:                XmNheight, h,
                    658:                XmNy, y,
                    659:                NULL);
                    660:        }
                    661:        else if (sb->update[which_sb] == SB_UPDATE_VALUE)
                    662:        {
                    663:            XtVaSetValues(sb->id[which_sb],
                    664:                XmNvalue, val,
                    665:                XmNsliderSize, size,
                    666:                XmNpageIncrement, (size > 2 ? size - 2 : 1),
                    667:                XmNmaximum, max,
                    668:                NULL);
                    669:        }
                    670:        sb->update[which_sb] = SB_UPDATE_NOTHING;
                    671:    }
                    672:
                    673:    /* Command line scrollbar */
                    674:    sb = &gui.cmdline_sb;
                    675:    max = sb->max + 1;          /* Motif has max one past the end */
                    676:    if (sb->update[which_sb] == SB_UPDATE_HEIGHT)
                    677:    {
                    678:        h = lastwin->w_status_height * (gui.char_height + 1) / 2;
                    679:        y = (Rows - sb->height) * gui.char_height - h;
                    680:        h += sb->height * gui.char_height;
                    681:
                    682:        /* Height of cmdline scrollbar includes width of bottom border */
                    683:        h += gui.border_offset;
                    684:
                    685:        XtVaSetValues(sb->id[which_sb],
                    686:            XmNvalue, sb->value,
                    687:            XmNsliderSize, sb->size,
                    688:            XmNmaximum, max,
                    689:            XmNheight, h,
                    690:            XmNy, y,
                    691:            NULL);
                    692:    }
                    693:    else if (sb->update[which_sb] == SB_UPDATE_VALUE)
                    694:    {
                    695:        XtVaSetValues(sb->id[which_sb],
                    696:            XmNvalue, sb->value,
                    697:            XmNsliderSize, sb->size,
                    698:            XmNmaximum, max,
                    699:            NULL);
                    700:    }
                    701:    sb->update[which_sb] = SB_UPDATE_NOTHING;
                    702:
                    703:    if (worst_update >= SB_UPDATE_HEIGHT)
                    704:    {
                    705:        if (worst_update >= SB_UPDATE_CREATE)
                    706:            gui_mch_reorder_scrollbars(which_sb);
                    707:        XtManageChild(scrollbarBox[which_sb]);
                    708:        gui_x11_use_resize_callback(textArea, TRUE);
                    709:    }
                    710: }
                    711:
                    712:    void
                    713: gui_mch_reorder_scrollbars(which_sb)
                    714:    int     which_sb;
                    715: {
                    716:    Widget *children;
                    717:    int     num_children;
                    718:    Widget  tmp;
                    719:    WIN     *wp, *wp2;
                    720:    int     i, j;
                    721:
                    722:    XtVaGetValues(scrollbarBox[which_sb],
                    723:        XmNchildren, &children,
                    724:        XmNnumChildren, &num_children,
                    725:        NULL);
                    726:
                    727:    /* Should be in same order as in the window list */
                    728:    wp = firstwin;
                    729:    for (i = 0; i < num_children; i++, wp = wp->w_next)
                    730:    {
                    731:        if (wp == NULL)
                    732:            break;      /* Shouldn't happen */
                    733:        if (wp->w_scrollbar.id[which_sb] != children[i])
                    734:        {
                    735:            /* It's in the wrong place, find what should go here */
                    736:            wp2 = wp->w_next;
                    737:            for (j = i + 1; j < num_children; j++, wp2 = wp2->w_next)
                    738:            {
                    739:                if (wp2 == NULL)
                    740:                    break;      /* Shouldn't happen */
                    741:                if (wp->w_scrollbar.id[which_sb] == children[j])
                    742:                    break;      /* Found it */
                    743:            }
                    744:            if (j >= num_children || wp2 == NULL)
                    745:                break;          /* Shouldn't happen */
                    746:            tmp = children[i];
                    747:            children[i] = children[j];
                    748:            children[j] = tmp;
                    749:        }
                    750:    }
                    751:
                    752:    XtVaSetValues(scrollbarBox[which_sb],
                    753:        XmNchildren, children,
                    754:        NULL);
                    755: }
                    756:
                    757:    void
                    758: gui_mch_destroy_scrollbar(wp)
                    759:    WIN     *wp;
                    760: {
                    761:    if (gui.which_scrollbars[SB_LEFT])
                    762:        XtDestroyWidget(wp->w_scrollbar.id[SB_LEFT]);
                    763:    if (gui.which_scrollbars[SB_RIGHT])
                    764:        XtDestroyWidget(wp->w_scrollbar.id[SB_RIGHT]);
                    765:    gui.num_scrollbars--;
                    766: }
                    767:
                    768:
                    769: /*
                    770:  * Horizontal scrollbar stuff:
                    771:  */
                    772:
                    773:    void
                    774: gui_mch_update_horiz_scrollbar(value, size, max)
                    775:    int     value;
                    776:    int     size;
                    777:    int     max;
                    778: {
                    779:    static int prev_value = -1, prev_size = -1, prev_max = -1;
                    780:
                    781:    if (value == prev_value && size == prev_size && max == prev_max)
                    782:        return;
                    783:
                    784:    prev_value = value;
                    785:    prev_size = size;
                    786:    prev_max = max;
                    787:
                    788:    XtVaSetValues(scrollbarBox[SB_BOTTOM],
                    789:        XmNvalue, value,
                    790:        XmNsliderSize, size,
                    791:        XmNpageIncrement, (size > 2 ? size - 2 : 1),
                    792:        XmNmaximum, max,
                    793:        NULL);
                    794: }
                    795:
                    796:    Window
                    797: gui_mch_get_wid()
                    798: {
                    799:    return( XtWindow(textArea) );
                    800: }