Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/VPane.c, revision 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.