[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

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: }