Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/VPane.c, revision 1.1.1.1

1.1       root        1: /* $Header: VPane.c,v 1.1 87/09/11 07:59:07 toddb Exp $ */
                      2: #ifndef lint
                      3: static char *sccsid = "@(#)VPane.c     1.10    2/25/87";
                      4: #endif lint
                      5: 
                      6: /*
                      7:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      8:  * 
                      9:  *                         All Rights Reserved
                     10:  * 
                     11:  * Permission to use, copy, modify, and distribute this software and its 
                     12:  * documentation for any purpose and without fee is hereby granted, 
                     13:  * provided that the above copyright notice appear in all copies and that
                     14:  * both that copyright notice and this permission notice appear in 
                     15:  * supporting documentation, and that the name of Digital Equipment
                     16:  * Corporation not be used in advertising or publicity pertaining to
                     17:  * distribution of the software without specific, written prior permission.  
                     18:  * 
                     19:  * 
                     20:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     21:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     22:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     23:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     24:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     25:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     26:  * SOFTWARE.
                     27:  */
                     28: 
                     29: 
                     30: /* VPane.c */
                     31: 
                     32: #include "Xlib.h"
                     33: #include "cursorfont.h"
                     34: #include "Intrinsic.h"
                     35: #include "VPane.h"
                     36: #include "Atoms.h"
                     37: 
                     38: /* Private definitions. */
                     39: 
                     40: 
                     41: #define BORDERWIDTH            1 /* Size of borders between panes. */
                     42:                                  /* %%% Should not be a constant! */
                     43: #define DEFAULTKNOBWIDTH       9
                     44: #define DEFAULTKNOBHEIGHT      9
                     45: #define DEFAULTKNOBINDENT      16
                     46: 
                     47: typedef struct {
                     48:     Display *dpy;              /* Display connection */
                     49:     Window w;                  /* Subwindow */
                     50:     Position y;                        /* Location in master window */
                     51:     Position dy;               /* Desired location. */
                     52:     Position olddy;            /* The last value of dy.  */
                     53:     Dimension min, max;                /* Minimum and maximum height. */
                     54:     short autochange;          /* Whether we're allowed to change this */
                     55:                                /* subwindow's height without an */
                     56:                                /* explicite command from user. */
                     57:     Dimension height;                  /* Current height. */
                     58:     Dimension dheight;         /* Desired height. */
                     59:     Window knob;               /* The knob for this subwindow. */
                     60:     Boolean allowresize;       /* Whether we should honor geometry requests */
                     61:                                /* from this window to change its height. */
                     62: } SubWindowInfo, *SubWindowPtr;
                     63: 
                     64: typedef struct {
                     65:     Display *dpy;              /* display connection for paned window */
                     66:     Window ourparent;          /* Parent of the paned window. */
                     67:     Window window;             /* Window containing everything. */
                     68:     Pixel foregroundpixel;     /* Foreground pixmap. */
                     69:     Pixel backgroundpixel;     /* Background pixmap. */
                     70:     Position x, y;             /* Location of master window. */
                     71:     Dimension width, height;   /* Dimension of master window. */
                     72:     Dimension borderWidth;     /* Borderwidth of master window. */
                     73:     Dimension borderpixel;     /* Color of border of master window. */
                     74:     Dimension knobwidth, knobheight; /* Dimension of knobs. */
                     75:     Position knobindent;       /* Location of knobs (offset from */
                     76:                                /* right margin.) */
                     77:     Pixel knobpixel;           /* Color of knobs. */
                     78:     Dimension heightused;      /* Total height used by subwindows. */
                     79:     int numsubwindows;         /* How many windows within it. */
                     80:     SubWindowInfo *sub;                /* Array of info about the sub windows. */
                     81:     int whichtracking;         /* Which knob we are tracking, if any */
                     82:     Position starty;           /* Starting y value. */
                     83:     int whichdirection;                /* Which direction to refigure things in. */
                     84:     SubWindowPtr whichadd;     /* Which subwindow to add changes to. */
                     85:     SubWindowPtr whichsub;     /* Which subwindow to sub changes from. */
                     86:     Boolean refiguremode;      /* Whether to refigure things right now. */
                     87:     GC normgc;                 /* GC to use when redrawing borders. */
                     88:     GC invgc;                  /* GC to use when erasing borders. */
                     89:     GC flipgc;                 /* GC to use when animating borders. */
                     90: } WidgetDataRec, *WidgetData;
                     91: 
                     92: static WidgetDataRec globaldata, globaldatainit;
                     93: 
                     94: static Resource resources[] = {
                     95:     {XtNwindow, XtCWindow, XrmRWindow, sizeof(Window),
                     96:         (caddr_t)&globaldata.window, NULL},
                     97:     {XtNforeground, XtCColor, XrmRPixel, sizeof(int),
                     98:         (caddr_t)&globaldata.foregroundpixel, (caddr_t)&XtDefaultFGPixel},
                     99:     {XtNbackground, XtCColor, XrmRPixel, sizeof(int),
                    100:         (caddr_t)&globaldata.backgroundpixel, (caddr_t)&XtDefaultBGPixel},
                    101:     {XtNx, XtCX, XrmRInt, sizeof(int),
                    102:         (caddr_t)&globaldata.x, NULL},
                    103:     {XtNy, XtCY, XrmRInt, sizeof(int),
                    104:         (caddr_t)&globaldata.y, NULL},
                    105:     {XtNwidth, XtCWidth, XrmRInt, sizeof(int),
                    106:         (caddr_t)&globaldata.width, NULL},
                    107:     {XtNheight, XtCHeight, XrmRInt, sizeof(int),
                    108:         (caddr_t)&globaldata.height, NULL},
                    109:     {XtNborderWidth, XtCBorderWidth, XrmRInt, sizeof(int),
                    110:         (caddr_t)&globaldata.borderWidth, NULL},
                    111:     {XtNborder, XtCColor, XrmRPixmap, sizeof(int),
                    112:         (caddr_t)&globaldata.borderpixel, (caddr_t)&XtDefaultFGPixel},
                    113:     {XtNknobWidth, XtCWidth, XrmRInt, sizeof(int),
                    114:         (caddr_t)&globaldata.knobwidth, NULL},
                    115:     {XtNknobHeight, XtCHeight, XrmRInt, sizeof(int),
                    116:         (caddr_t)&globaldata.knobheight, NULL},
                    117:     {XtNknobIndent, XtCKnobIndent, XrmRInt, sizeof(int),
                    118:         (caddr_t)&globaldata.knobindent, NULL},
                    119:     {XtNknobPixel, XtCKnobPixel, XrmRPixel, sizeof(int),
                    120:         (caddr_t)&globaldata.knobpixel, (caddr_t)&globaldata.foregroundpixel},
                    121: };
                    122: 
                    123: static XContext widgetContext;
                    124: static int CursorNums[4] = {0,
                    125:                            XC_sb_up_arrow,
                    126:                            XC_sb_v_double_arrow,
                    127:                            XC_sb_down_arrow};
                    128: 
                    129: static WidgetData DataFromWindow(dpy, w)
                    130:   Display *dpy;
                    131:   Window w;
                    132: {
                    133:     WidgetData data;
                    134:     if (XFindContext(dpy, w, widgetContext, (caddr_t *) &data)) return 0;
                    135:     return data;
                    136: }
                    137: 
                    138: static void TryResize(data, newwidth, newheight)
                    139:   WidgetData data;
                    140:   Dimension newwidth, newheight;
                    141: {
                    142:     WindowBox requestBox, replyBox;
                    143:     XtGeometryReturnCode result;
                    144:     requestBox.x = 0;
                    145:     requestBox.y = 0;
                    146:     if (newwidth < 1) newwidth = 1;
                    147:     if (newheight < 1) newheight = 1;
                    148:     requestBox.width = newwidth;
                    149:     requestBox.height = newheight;
                    150:     result = XtMakeGeometryRequest(data->dpy, data->window, XtgeometryResize,
                    151:                                   &requestBox, &replyBox);
                    152:     if (result == XtgeometryAlmost) {
                    153:        requestBox = replyBox;
                    154:        result = XtMakeGeometryRequest(data->dpy, data->window, XtgeometryResize,
                    155:                                       &requestBox, &replyBox);
                    156:     }
                    157:     if (result == XtgeometryYes) {
                    158:        data->width = replyBox.width;
                    159:        data->height = replyBox.height;
                    160:     }
                    161: }
                    162: 
                    163: 
                    164: static RefigureLocations(data, position, dir)
                    165:   WidgetData data;
                    166:   int position;
                    167:   int dir;             /* -1 = up, 1 = down, 0 = this border only */
                    168: {
                    169:     SubWindowPtr sub, firstsub;
                    170:     int     i, old, y, cdir;
                    171:     if (data->numsubwindows == 0 || !data->refiguremode)
                    172:        return;
                    173:     do {
                    174:        data->heightused = 0;
                    175:        for (i = 0, sub = data->sub; i < data->numsubwindows; i++, sub++) {
                    176:            if (sub->dheight < sub->min)
                    177:                sub->dheight = sub->min;
                    178:            if (sub->dheight > sub->max)
                    179:                sub->dheight = sub->max;
                    180:            data->heightused += sub->dheight;
                    181:        }
                    182:        data->heightused += BORDERWIDTH * (data->numsubwindows - 1);
                    183:        if (dir == 0 && data->heightused != data->height) {
                    184:            for (i = 0, sub = data->sub; i < data->numsubwindows; i++, sub++)
                    185:                if (sub->dheight != sub->height)
                    186:                    sub->dheight += data->height - data->heightused;
                    187:        }
                    188:     } while (dir == 0 && data->heightused != data->height);
                    189: 
                    190:     firstsub = data->sub + position;
                    191:     sub = firstsub;
                    192:     cdir = dir;
                    193:     while (data->heightused != data->height) {
                    194:        if (sub->autochange || cdir != dir) {
                    195:            old = sub->dheight;
                    196:            sub->dheight = data->height - data->heightused + old;
                    197:            if (sub->dheight < sub->min)
                    198:                sub->dheight = sub->min;
                    199:            if (sub->dheight > sub->max)
                    200:                sub->dheight = sub->max;
                    201:            data->heightused += (sub->dheight - old);
                    202:        }
                    203:        sub += cdir;
                    204:        while (sub < data->sub || sub - data->sub == data->numsubwindows) {
                    205:            cdir = -cdir;
                    206:            if (cdir == dir) goto doublebreak;
                    207:            sub = firstsub + cdir;
                    208:        }
                    209:     }
                    210: doublebreak:
                    211:     y = -BORDERWIDTH;
                    212:     for (i = 0, sub = data->sub; i < data->numsubwindows; i++, sub++) {
                    213:        sub->dy = y;
                    214:        y += sub->dheight + BORDERWIDTH;
                    215:     }
                    216: }
                    217: 
                    218: 
                    219: static CommitNewLocations(data)
                    220:   WidgetData data;
                    221: {
                    222:     int i, kx, ky;
                    223:     SubWindowPtr sub;
                    224:     if (data->heightused != data->height)
                    225:        TryResize(data, data->width, data->height);
                    226:     for (i = 0, sub = data->sub; i < data->numsubwindows; i++, sub++) {
                    227:        if (sub->dy != sub->y || sub->dheight != sub->height) {
                    228:            WindowBox box;
                    229:            XMoveResizeWindow(data->dpy, sub->w,
                    230:                             box.x = -BORDERWIDTH,
                    231:                             box.y = sub->dy,
                    232:                             box.width = data->width,
                    233:                             box.height = sub->dheight);
                    234:            sub->y = sub->dy;
                    235:            sub->height = sub->dheight;
                    236:            (void) XtSendConfigureNotify(data->dpy, sub->w, &box);
                    237:            kx = data->width - data->knobindent;
                    238:            ky = sub->y + sub->height - (data->knobheight/2)+1;
                    239:            if (i == data->numsubwindows - 1)
                    240:                ky = -99;       /* Keep the last knob hidden. */
                    241:            XMoveWindow(data->dpy, sub->knob, kx, ky);
                    242:            XRaiseWindow(data->dpy,sub->knob);
                    243: 
                    244:        }
                    245:     }
                    246: /*    kx = data->width - data->knobindent;
                    247:     for (i = 0, sub = data->sub; i < data->numsubwindows; i++, sub++) {
                    248:        ky = sub->y + sub->height - (data->knobheight / 2) + 1;
                    249:        if (i == data->numsubwindows - 1)
                    250:            ky = -99;
                    251:        XMoveWindow(data->dpy, sub->knob, kx, ky);
                    252:        XRaiseWindow(data->dpy, sub->knob);
                    253:     }*/
                    254: }
                    255: 
                    256: 
                    257: static RefigureLocationsAndCommit(data, position, dir)
                    258:   WidgetData data;
                    259:   int position, dir;
                    260: {
                    261:     RefigureLocations(data, position, dir);
                    262:     CommitNewLocations(data);
                    263: }
                    264: 
                    265: 
                    266: EraseInternalBorders(data)
                    267:   WidgetData data;
                    268: {
                    269:     int     i;
                    270:     for (i = 1; i < data->numsubwindows; i++)
                    271:        XFillRectangle(data->dpy, data->window, data->invgc,
                    272:                       0, data->sub[i].y, data->width, BORDERWIDTH);
                    273: }
                    274: 
                    275: 
                    276: DrawInternalBorders(data)
                    277:   WidgetData data;
                    278: {
                    279:     int     i;
                    280:     for (i = 1; i < data->numsubwindows; i++)
                    281:        XFillRectangle(data->dpy, data->window, data->normgc,
                    282:                       0, data->sub[i].y, data->width, BORDERWIDTH);
                    283: }
                    284: 
                    285: 
                    286: static DrawTrackLines(data)
                    287:   WidgetData data;
                    288: {
                    289:     int     i;
                    290:     SubWindowPtr sub;
                    291:     for (i = 1, sub = data->sub + 1; i < data->numsubwindows; i++, sub++) {
                    292:        if (sub->olddy != sub->dy) {
                    293:            XDrawLine(data->dpy, data->window, data->flipgc,
                    294:                  0, sub->olddy, (Position) data->width, sub->olddy);
                    295:            XDrawLine(data->dpy, data->window, data->flipgc,
                    296:                  0, sub->dy, (Position) data->width, sub->dy);
                    297:            sub->olddy = sub->dy;
                    298:        }
                    299:     }
                    300: }
                    301: 
                    302: static EraseTrackLines(data)
                    303:   WidgetData data;
                    304: {
                    305:     int     i;
                    306:     SubWindowPtr sub;
                    307:     for (i = 1, sub = data->sub + 1; i < data->numsubwindows; i++, sub++)
                    308:        XDrawLine(data->dpy, data->window, data->flipgc,
                    309:              0, sub->olddy, (Position) data->width, sub->olddy);
                    310: }
                    311: 
                    312: 
                    313: /* Semi-public routines. */
                    314: 
                    315: static XtGeometryReturnCode PanedWindowGeometryRequest(
                    316:                                      dpy, w, request, reqBox, replBox)
                    317: Display *dpy;
                    318: Window w;
                    319: XtGeometryRequest request;
                    320: WindowBox *reqBox, *replBox;
                    321: {
                    322:     WidgetData data;
                    323:     int i;
                    324:     SubWindowPtr sub;
                    325: 
                    326:     data = DataFromWindow(dpy, w);
                    327:     if (!data) return XtgeometryNo;
                    328:     for (i=0 ; i<data->numsubwindows ; i++)
                    329:        if (data->sub[i].w == w) break;
                    330:     if (i >= data->numsubwindows) return XtgeometryNo;
                    331:     sub = data->sub + i;
                    332:     if (request == XtgeometryResize) {
                    333:        if (!sub->allowresize) return XtgeometryNo;
                    334:        if (data->width != reqBox->width) {
                    335:            if (sub->height == reqBox->height)
                    336:                return XtgeometryNo;
                    337:            *replBox = *reqBox;
                    338:            replBox->width = data->width;
                    339:            return XtgeometryAlmost;
                    340:        }
                    341:        if (sub->min == sub->height || sub->min > reqBox->height)
                    342:            sub->min = reqBox->height;
                    343:        if (sub->max == sub->height || sub->max < reqBox->height)
                    344:            sub->max = reqBox->height;
                    345:        sub->dheight = reqBox->height;
                    346:        RefigureLocationsAndCommit(data, i, 1);
                    347:        return XtgeometryYes;
                    348:     }
                    349:     if (request == XtgeometryGetWindowBox) {
                    350:        replBox->x = -BORDERWIDTH;
                    351:        replBox->y = sub->y;
                    352:        replBox->width = data->width;
                    353:        replBox->height = sub->height;
                    354:        replBox->borderWidth = BORDERWIDTH;
                    355:        return XtgeometryYes;
                    356:     }
                    357:     return XtgeometryNo;
                    358: }
                    359: 
                    360: static XtEventReturnCode HandleEvents(event)
                    361:   XEvent *event;
                    362: {
                    363:     WidgetData data;
                    364:     WindowBox box;
                    365:     int i;
                    366: 
                    367:     data = DataFromWindow(event->xany.display, event->xany.window);
                    368:     if (!data) return XteventNotHandled;
                    369:     switch (event->type) {
                    370:       case ConfigureNotify:
                    371:        if (data->width != event->xconfigure.width ||
                    372:              data->height != event->xconfigure.height) {
                    373:            if (data->width != event->xconfigure.width) {
                    374:                box.x = -BORDERWIDTH;
                    375:                box.width = event->xconfigure.width;
                    376:                box.borderWidth = BORDERWIDTH;
                    377:                for (i = 0; i < data->numsubwindows; i++) {
                    378:                    XResizeWindow(data->dpy, data->sub[i].w,
                    379:                                  (Dimension) event->xconfigure.width,
                    380:                                  (Dimension) data->sub[i].height);
                    381:                    box.y = data->sub[i].y;
                    382:                    box.height = data->sub[i].height;
                    383:                    (void) XtSendConfigureNotify(data->dpy, data->sub[i].w,
                    384:                                                 &box);
                    385:                }
                    386:            }
                    387:            data->width = event->xconfigure.width;
                    388:            data->height = event->xconfigure.height;
                    389:            RefigureLocationsAndCommit(data, data->numsubwindows - 1, -1);
                    390:        }
                    391:        data->x = event->xconfigure.x;
                    392:        data->y = event->xconfigure.y;
                    393:        data->borderWidth = event->xconfigure.border_width;
                    394:        return XteventHandled;
                    395:       case DestroyNotify:
                    396:        data->refiguremode = FALSE;
                    397:        for (i = data->numsubwindows-1 ; i >= 0 ; i--)
                    398:            (void) XtSendDestroyNotify(data->dpy, data->sub[i].w);
                    399:        (void) XDeleteContext(data->dpy, data->window, widgetContext);
                    400:        XtClearEventHandlers(data->dpy, data->window);
                    401:        XtFree((char *)data->sub);
                    402:        XtFree((char *)data);
                    403:        return XteventHandled;
                    404:     }
                    405:     return XteventNotHandled;
                    406: }
                    407: 
                    408: static XtEventReturnCode HandleSubwindow(event)
                    409:   XEvent *event;
                    410: {
                    411:     WidgetData data;
                    412:     if (event->type == DestroyNotify) {
                    413:        data = DataFromWindow(event->xdestroywindow.display, event->xdestroywindow.window);
                    414:        if (data) {
                    415:            XtVPanedWindowDeletePane(data->dpy, data->window,
                    416:                                     event->xdestroywindow.window);
                    417:            return XteventHandled;
                    418:        }
                    419:     }
                    420:     return XteventNotHandled;
                    421: }
                    422: 
                    423: static XtEventReturnCode HandleKnob(event)
                    424:   XEvent *event;
                    425: {
                    426:     WidgetData data;
                    427:     int     position, diff, y, i;
                    428: 
                    429:     data = DataFromWindow(event->xbutton.display, event->xbutton.window);
                    430:     if (!data) return XteventNotHandled;
                    431:     switch (event->type) {
                    432:        case ButtonPress: 
                    433:            y = event->xbutton.y;
                    434:            if (data->whichtracking != -1)
                    435:                return XteventNotHandled;
                    436:            for (position = 0; position < data->numsubwindows; position++)
                    437:                if (data->sub[position].knob == event->xbutton.window)
                    438:                    break;
                    439:            if (position >= data->numsubwindows)
                    440:                return XteventNotHandled;
                    441:            
                    442:            (void) XGrabPointer(data->dpy, event->xbutton.window, FALSE,
                    443:                                (unsigned int)PointerMotionMask | ButtonReleaseMask,
                    444:                                GrabModeAsync, GrabModeAsync, None,
                    445:                                XtGetCursor(data->dpy,
                    446:                                            CursorNums[event->xbutton.button]),
                    447:                                CurrentTime);
                    448:            data->whichadd = data->whichsub = NULL;
                    449:            data->whichdirection = 2 - event->xbutton.button;/* Hack! */
                    450:            data->starty = y;
                    451:            if (data->whichdirection >= 0) {
                    452:                data->whichadd = data->sub + position;
                    453:                while (data->whichadd->max == data->whichadd->min &&
                    454:                        data->whichadd > data->sub)
                    455:                    (data->whichadd)--;
                    456:            }
                    457:            if (data->whichdirection <= 0) {
                    458:                data->whichsub = data->sub + position + 1;
                    459:                while (data->whichsub->max == data->whichsub->min &&
                    460:                        data->whichsub < data->sub + data->numsubwindows - 1)
                    461:                    (data->whichsub)++;
                    462:            }
                    463:            data->whichtracking = position;
                    464:            if (data->whichdirection == 1)
                    465:                (data->whichtracking)++;
                    466:            EraseInternalBorders(data);
                    467:            for (i = 0; i < data->numsubwindows; i++)
                    468:                data->sub[i].olddy = -99;
                    469:        /* Fall through */
                    470: 
                    471:        case MotionNotify: 
                    472:        case ButtonRelease:
                    473:            if (event->type == MotionNotify) y = event->xmotion.y;
                    474:            else y = event->xbutton.y;
                    475:            if (data->whichtracking == -1)
                    476:                return XteventNotHandled;
                    477:            for (i = 0; i < data->numsubwindows; i++)
                    478:                data->sub[i].dheight = data->sub[i].height;
                    479:            diff = y - data->starty;
                    480:            if (data->whichadd)
                    481:                data->whichadd->dheight = data->whichadd->height + diff;
                    482:            if (data->whichsub)
                    483:                data->whichsub->dheight = data->whichsub->height - diff;
                    484:            RefigureLocations(data, data->whichtracking, data->whichdirection);
                    485: 
                    486:            if (event->type != ButtonRelease) {
                    487:                DrawTrackLines(data);/* Draw new borders */
                    488:                return XteventHandled;
                    489:            }
                    490:            XUngrabPointer(data->dpy, CurrentTime);
                    491:            EraseTrackLines(data);
                    492:            CommitNewLocations(data);
                    493:            DrawInternalBorders(data);
                    494:            data->whichtracking = -1;
                    495:            return XteventHandled;
                    496:     }
                    497:     return XteventNotHandled;
                    498: }
                    499:   
                    500: 
                    501: /* Public routines. */
                    502: 
                    503: static Boolean initialized = FALSE;
                    504: 
                    505: extern void VPanedInitialize()
                    506: {
                    507:     if (initialized)
                    508:        return;
                    509:     initialized = TRUE;
                    510: 
                    511:     widgetContext = XUniqueContext();
                    512:     globaldatainit.window = NULL;
                    513:     globaldatainit.x = globaldatainit.y = 0;
                    514:     globaldatainit.width = globaldatainit.height = 10;
                    515:     globaldatainit.borderWidth = 1;
                    516:     globaldatainit.knobwidth = DEFAULTKNOBWIDTH;
                    517:     globaldatainit.knobheight = DEFAULTKNOBHEIGHT;
                    518:     globaldatainit.knobindent = DEFAULTKNOBINDENT;
                    519: }
                    520: 
                    521: 
                    522: Window XtVPanedWindowCreate(dpy, parent, args, argCount)
                    523:     Display  *dpy;
                    524:     Window   parent;
                    525:     ArgList  args;
                    526:     int      argCount;
                    527: {
                    528:     WidgetData data;
                    529:     XrmNameList        names;
                    530:     XrmClassList       classes;
                    531:     unsigned long valuemask;
                    532:     XSetWindowAttributes wvals;
                    533:     XGCValues values;
                    534: 
                    535:     if (!initialized) VPanedInitialize();
                    536: 
                    537:     data = (WidgetData) XtMalloc(sizeof(WidgetDataRec));
                    538:     globaldata = globaldatainit;
                    539:     globaldata.dpy = dpy;
                    540:     XtGetResources(dpy, resources, XtNumber(resources), args, argCount, parent,
                    541:        "vpane", "VPane", &names, &classes);
                    542:     *data = globaldata;
                    543: 
                    544:     wvals.background_pixel = data->backgroundpixel;
                    545:     wvals.border_pixel = data->borderpixel;
                    546:     wvals.bit_gravity = NorthWestGravity;
                    547:     valuemask = CWBackPixel | CWBorderPixel | CWBitGravity;
                    548: 
                    549:     if (data->window != NULL) {
                    550:        Drawable root;
                    551:        Position x, y;
                    552:        unsigned int depth;
                    553:        (void) XGetGeometry(data->dpy, data->window, &root, &x, &y,
                    554:                            &(data->width), &(data->height), &(data->borderWidth),
                    555:                            &depth);
                    556:        XReparentWindow(data->dpy, data->window, parent, data->x, data->y);
                    557:        XChangeWindowAttributes(data->dpy, data->window, valuemask, &wvals);
                    558:     } else {
                    559:        data->window = XCreateWindow(data->dpy, parent, data->x, data->y,
                    560:                              data->width, data->height, data->borderWidth,
                    561:                              (int) CopyFromParent, InputOutput,
                    562:                              (Visual *) CopyFromParent, valuemask, &wvals);
                    563:     }
                    564: 
                    565:     values.foreground = data->foregroundpixel;
                    566:     values.function = GXcopy;
                    567:     values.plane_mask = ~0;
                    568:     values.fill_style = FillSolid;
                    569:     values.fill_rule = EvenOddRule;
                    570:     values.subwindow_mode = IncludeInferiors;
                    571:     valuemask = GCForeground | GCFunction | GCPlaneMask | GCFillStyle
                    572:        | GCFillRule | GCSubwindowMode;
                    573:     data->normgc = XtGetGC(dpy, widgetContext, data->window, valuemask, &values);
                    574:     values.foreground = data->backgroundpixel;
                    575:     data->invgc = XtGetGC(dpy, widgetContext, data->window, valuemask, &values);
                    576:     values.function = GXinvert;
                    577: #if BORDERWIDTH == 1
                    578:     values.line_width = 0;     /* Take advantage of fast server lines. */
                    579: #else
                    580:     values.line_width = BORDERWIDTH;
                    581: #endif
                    582:     values.line_style = LineSolid;
                    583:     valuemask |= GCLineWidth | GCLineStyle;
                    584:     data->flipgc = XtGetGC(dpy, widgetContext, data->window, valuemask, &values);
                    585: 
                    586:     XtSetNameAndClass(data->dpy, data->window, names, classes);
                    587:     XrmFreeNameList(names);
                    588:     XrmFreeClassList(classes);
                    589:     data->heightused = 0;
                    590:     data->numsubwindows = 0;
                    591:     data->sub = (SubWindowInfo *) XtMalloc(1);
                    592:     data->whichtracking = -1;
                    593:     data->refiguremode = TRUE;
                    594:     (void) XSaveContext(data->dpy, data->window, widgetContext, (caddr_t) data);
                    595:     (void) XtSetEventHandler(data->dpy, data->window, HandleEvents, StructureNotifyMask,
                    596:      (caddr_t) NULL);
                    597:     return data->window;
                    598: }
                    599: 
                    600: 
                    601: void XtVPanedWindowDelete(dpy, w)
                    602:     Display *dpy;
                    603:     Window w;
                    604: {
                    605:     WidgetData data;
                    606:     int i;
                    607:     data = DataFromWindow(dpy, w);
                    608:     XUnmapWindow(data->dpy, w);
                    609:     for (i=data->numsubwindows-1 ; i>=0 ; i--) 
                    610:        XtVPanedWindowDeletePane(dpy, w, data->sub[i].w);
                    611:     (void) XDeleteContext(dpy, w, widgetContext);
                    612:     XtFree((char *) data->sub);
                    613:     XtFree((char *) data);
                    614: }
                    615: 
                    616: 
                    617: 
                    618: void XtVPanedWindowAddPane(
                    619:        dpy, parent, paneWindow, position, min, max, autochange)
                    620:     Display *dpy;
                    621:     Window parent, paneWindow;
                    622:     int position, min, max, autochange;
                    623: {
                    624:     WidgetData data;
                    625:     Drawable root;
                    626:     int i;
                    627:     Position x;
                    628:     Dimension width, borderWidth, needed;
                    629:     unsigned int depth;
                    630:     SubWindowPtr sub;
                    631:     data = DataFromWindow(dpy, parent);
                    632:     if (!data) return;
                    633:     if (position > 0 && position == data->numsubwindows)
                    634:        data->sub[position - 1].y = -99; /* HACK to make knob reappear. */
                    635:     data->numsubwindows++;
                    636:     data->sub = (SubWindowPtr)
                    637:        XtRealloc((char *) data->sub,
                    638:                  (unsigned) data->numsubwindows * sizeof(SubWindowInfo));
                    639:     for (i = data->numsubwindows - 1; i > position; i--)
                    640:        data->sub[i] = data->sub[i - 1];
                    641:     sub = &(data->sub[position]);
                    642:     sub->w = paneWindow;
                    643:     (void) XGetGeometry(data->dpy, paneWindow, &root, &x, &(sub->y),
                    644:                        &width, &(sub->height), &borderWidth, &depth);
                    645:     XReparentWindow(data->dpy, paneWindow, data->window, -BORDERWIDTH,
                    646:                    sub->y);
                    647:     sub->dheight = sub->height;
                    648:     if (width != data->width || borderWidth != BORDERWIDTH) {
                    649:        XWindowChanges changes;
                    650:        changes.width = data->width;
                    651:        changes.border_width = BORDERWIDTH;
                    652:        XConfigureWindow(data->dpy, paneWindow,
                    653:                         (unsigned int) CWWidth | CWBorderWidth, &changes);
                    654:     }
                    655:     sub->min = min;
                    656:     sub->max = max;
                    657:     sub->autochange = autochange;
                    658:     needed = sub->height + BORDERWIDTH + data->heightused;
                    659:     if (needed > data->height)
                    660:        TryResize(data, data->width, needed);
                    661:     (void) XtSetGeometryHandler(data->dpy, paneWindow, PanedWindowGeometryRequest);
                    662:     sub->knob = XCreateSimpleWindow(data->dpy, data->window, -99, -99,
                    663:                              data->knobwidth, data->knobheight,
                    664:                              0, (Pixel) 0, data->knobpixel);
                    665:     (void) XSaveContext(dpy, sub->w, widgetContext, (caddr_t) data);
                    666:     (void) XSaveContext(dpy, sub->knob, widgetContext, (caddr_t) data);
                    667:     XDefineCursor(data->dpy, sub->knob, XtGetCursor(dpy, XC_double_arrow));
                    668:     XMapWindow(data->dpy, sub->w);
                    669:     XMapWindow(data->dpy, sub->knob);
                    670:     (void) XtSetEventHandler(dpy, sub->w, HandleSubwindow, StructureNotifyMask,
                    671:      (caddr_t) NULL);
                    672:     (void) XtSetEventHandler(dpy, sub->knob, HandleKnob, 
                    673:                        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
                    674:                        (caddr_t) NULL);
                    675:     RefigureLocationsAndCommit(data, position, 1);
                    676:     for (i=0 ; i<data->numsubwindows; i++)
                    677:        XRaiseWindow(data->dpy, data->sub[i].knob);
                    678: }
                    679: 
                    680: 
                    681: /* Change the min and max size of the given sub window. */
                    682: 
                    683: void XtVPanedSetMinMax(dpy, w, paneWindow, min, max)
                    684: Display *dpy;
                    685: Window w, paneWindow;
                    686: int    min, max;
                    687: {
                    688:     WidgetData data;
                    689:     int i;
                    690:     data = DataFromWindow(dpy, w);
                    691:     if (!data)
                    692:        return;
                    693:     for (i = 0; i < data->numsubwindows; i++) {
                    694:        if (data->sub[i].w == paneWindow) {
                    695:            data->sub[i].min = min;
                    696:            data->sub[i].max = max;
                    697:            RefigureLocationsAndCommit(data, i, 1);
                    698:            return;
                    699:        }
                    700:     }
                    701: }
                    702: 
                    703: 
                    704: /* Get the min and max size of the given sub window. */
                    705: 
                    706: void XtVPanedGetMinMax(dpy, w, paneWindow, min, max)
                    707: Display *dpy;
                    708: Window w, paneWindow;
                    709: int    *min, *max;
                    710: {
                    711:     WidgetData data;
                    712:     int i;
                    713:     data = DataFromWindow(dpy, w);
                    714:     if (!data)
                    715:        return;
                    716:     for (i = 0; i < data->numsubwindows; i++) {
                    717:        if (data->sub[i].w == paneWindow) {
                    718:            *min = data->sub[i].min;
                    719:            *max = data->sub[i].max;
                    720:            return;
                    721:        }
                    722:     }
                    723: }
                    724: 
                    725: 
                    726: 
                    727: /* Delete the given paneWindow from the given paned window.  Doesn't actually
                    728:    destroy the paneWindow. */
                    729: 
                    730: void XtVPanedWindowDeletePane(dpy, w, paneWindow)
                    731:     Display *dpy;
                    732:     Window w, paneWindow;
                    733: {
                    734:     WidgetData data;
                    735:     int     i;
                    736:     Boolean j;
                    737: 
                    738:     data = DataFromWindow(dpy, w);
                    739:     if (!data)
                    740:        return;
                    741:     j = FALSE;
                    742:     for (i = 0; i < data->numsubwindows; i++) {
                    743:        if (data->sub[i].w == paneWindow) {
                    744:            j = TRUE;
                    745:            (void) XDeleteContext(dpy, data->sub[i].w, widgetContext);
                    746:            (void) XDeleteContext(dpy, data->sub[i].knob, widgetContext);
                    747:            (void) XtSetEventHandler(dpy, data->sub[i].w, HandleSubwindow,
                    748:             (unsigned long) NULL, (caddr_t) NULL);
                    749:            XtClearEventHandlers(dpy, data->sub[i].knob);
                    750:            XDestroyWindow(data->dpy, data->sub[i].knob);
                    751:            TryResize(data, data->width,
                    752:                      data->height - data->sub[i].height - BORDERWIDTH);
                    753:        }
                    754:        if (j && i < data->numsubwindows - 1)
                    755:            data->sub[i] = data->sub[i + 1];
                    756:     }
                    757:     if (!j)
                    758:        return;
                    759:     data->numsubwindows--;
                    760:     if (data->numsubwindows > 0) {
                    761:        data->sub = (SubWindowPtr)
                    762:            XtRealloc((char *) data->sub,
                    763:             (unsigned) data->numsubwindows * sizeof(SubWindowInfo));
                    764:     }
                    765:     RefigureLocationsAndCommit(data, data->numsubwindows - 1, -1);
                    766: }
                    767: 
                    768: 
                    769: void XtVPanedAllowResize(dpy, window, paneWindow, allowresize)
                    770:     Display *dpy;
                    771:     Window window, paneWindow;
                    772:     Boolean  allowresize;
                    773: {
                    774:     WidgetData data;
                    775:     int i;
                    776:     data = DataFromWindow(dpy, window);
                    777:     if (data)
                    778:        for (i=0 ; i<data->numsubwindows ; i++)
                    779:            if (data->sub[i].w == paneWindow)
                    780:                data->sub[i].allowresize = allowresize;
                    781: }
                    782: 
                    783: 
                    784: 
                    785: Boolean XtVPanedGetResize(dpy, window, paneWindow)
                    786:     Display *dpy;
                    787:     Window window, paneWindow;
                    788: {
                    789:     WidgetData data;
                    790:     int i;
                    791:     data = DataFromWindow(dpy, window);
                    792:     if (data)
                    793:        for (i=0 ; i<data->numsubwindows ; i++)
                    794:            if (data->sub[i].w == paneWindow)
                    795:                return(data->sub[i].allowresize);
                    796:     return (0);
                    797: }
                    798: 
                    799: 
                    800: 
                    801: int XtVPanedGetNumSub(dpy, window)
                    802:     Display *dpy;
                    803:     Window window;
                    804: {
                    805:     WidgetData data;
                    806:     int i;
                    807:     data = DataFromWindow(dpy, window);
                    808:     if (data)
                    809:         return(data->numsubwindows);
                    810:     return (0);
                    811: }
                    812: 
                    813: 
                    814: 
                    815: 
                    816: void XtVPanedRefigureMode(dpy, window, mode)
                    817:   Display *dpy;
                    818:   Window window;
                    819:   Boolean  mode;
                    820: {
                    821:     WidgetData data;
                    822:     data = DataFromWindow(dpy, window);
                    823:     if (data) {
                    824:        data->refiguremode = mode;
                    825:        if (mode)
                    826:            RefigureLocationsAndCommit(data, data->numsubwindows - 1, -1);
                    827:     }
                    828: }
                    829: 
                    830: void XtVPaneGetValues(dpy, window, args, argCount)
                    831: Display *dpy;
                    832: Window window;
                    833: ArgList args;
                    834: int argCount;
                    835: {
                    836:     WidgetData data;
                    837:     data = DataFromWindow(dpy, window);
                    838:     if (data == NULL) return;
                    839: 
                    840:     globaldata = *data;
                    841:     XtGetValues(resources, XtNumber(resources), args, argCount);
                    842: }
                    843: 
                    844: void XtVPaneSetValues(dpy, window, args, argCount)
                    845: Display *dpy;
                    846: Window window;
                    847: ArgList args;
                    848: int argCount;
                    849: {
                    850:     WidgetData data;
                    851:     data = DataFromWindow(dpy, window);
                    852:     if (data == NULL) return;
                    853: 
                    854:     globaldata = *data;
                    855:     XtSetValues(resources, XtNumber(resources), args, argCount);
                    856:     *data = globaldata;
                    857: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.