Annotation of researchv9/X11/src/X.V11R1/clients/uwm/RubberBand.c, revision 1.1

1.1     ! root        1: /* $Header: RubberBand.c,v 1.20 87/09/02 15:28:22 swick Exp $ */
        !             2: /* derived from XCreateTerm.c */
        !             3: 
        !             4: #include <X11/copyright.h>
        !             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:  * MODIFICATION HISTORY
        !            31:  *
        !            32:  * 000 -- Loretta Guarino Reid, DEC Ultrix Engineering Group
        !            33:  * 001 -- Ralph R. Swick, DEC/MIT Project Athena
        !            34:  *       tailor to uwm; use global resources created by uwm
        !            35:  */
        !            36: 
        !            37: #include <stdio.h>
        !            38: #include <strings.h>
        !            39: #include <X11/Xlib.h>
        !            40: #include <X11/Xutil.h>
        !            41: #include <X11/cursorfont.h>
        !            42: 
        !            43: #include "uwm.h"
        !            44: 
        !            45: #define max(a,b) ( (a) > (b) ? (a) : (b) )
        !            46: #define min(a,b) ( (a) > (b) ? (b) : (a) )
        !            47: #define abs(a) ( (a) > 0 ? (a) : -(a))
        !            48: #define makemult(a, b) ((b==1) ? (a) : (((int)((a) / (b))) * (b)) )
        !            49: 
        !            50: #define DCOUNT 2
        !            51: #define PCOUNT 1 + (4 * 2 * DCOUNT)
        !            52: 
        !            53: #define BW     PBorderWidth            /* pop-up window border width */
        !            54: #define IBW    PPadding                /* internal border width for pop-up */
        !            55: 
        !            56: AskUser(dpy, scr, window, x, y, width, height, hints)
        !            57:        Display *dpy;
        !            58:        int scr;
        !            59:        Window window;
        !            60:        int *x, *y, *width, *height;
        !            61:        XSizeHints *hints;
        !            62:        {
        !            63:        /* XFontStruct *pfont; */
        !            64: #define pfont  PFontInfo               /* text font for pop-up */
        !            65:        Cursor ur, ul, ll, lr;          /* cursors for rubber banding    */
        !            66:        int change_cursor = FALSE;
        !            67:         int current_cursor;
        !            68:         char *text;                    /* text for prompt string       */
        !            69:         int nz;                         /* count where zeros are        */
        !            70:         int popw, poph;                 /* width and height of prompt window*/
        !            71:         /* int pfore, pback; */         /* prompt foreground and background */
        !            72: #define pback   PTextBackground
        !            73:        /* GC popGC, invertGC; */
        !            74:        /* XGCValues xgc; */
        !            75: #define popGC   PopGC
        !            76: #define invertGC DrawGC
        !            77:         int x1, y1;                     /* location of mouse            */
        !            78:         int x2, y2;                     /* other corner of box          */
        !            79:         int rootx, rooty, mask;         /* for XQueryPointer          */
        !            80:        Window root, subw;              /* for XQueryPointer */
        !            81:         int xa = -1, ya = -1, xb = -1, yb = -1;
        !            82:         int xinc, yinc;
        !            83:         int minwidth, minheight;
        !            84:         int maxwidth, maxheight;
        !            85:         int defwidth, defheight;
        !            86:         int chosen = -1;
        !            87:         int stop = FALSE;
        !            88:         int changed = TRUE;
        !            89:         int doit = FALSE;
        !            90:         int dx, dy;
        !            91:        int delta;
        !            92:        XPoint box[PCOUNT];
        !            93:         int hsize, vsize;
        !            94:         int zero = '0';                 /* zero offset for char conversion  */
        !            95:         XEvent e;                 /* someplace to put the event   */
        !            96:         int events;                     /* what events we want.             */
        !            97:         Window pop;                     /* pop up prompt window         */
        !            98:        int i;
        !            99:        char *name;
        !           100:        int width_offset, height_offset; /* to subtract if resize increments */
        !           101: 
        !           102:        if ((hints->flags & USPosition) && (hints->flags & USSize)) {
        !           103:          *x = hints->x;
        !           104:          *y = hints->y;
        !           105:          *width = hints->width;
        !           106:          *height = hints->height;
        !           107:          return;
        !           108:        }
        !           109:         if (!XFetchName(dpy, window, &name)) 
        !           110:          name = "Unnamed Window";
        !           111: 
        !           112:        ur = XCreateFontCursor(dpy, XC_ur_angle);
        !           113:        ul = XCreateFontCursor(dpy, XC_ul_angle);
        !           114:        ll = XCreateFontCursor(dpy, XC_ll_angle);
        !           115:        lr = XCreateFontCursor(dpy, XC_lr_angle);
        !           116:        current_cursor = ul;
        !           117: 
        !           118:        events = ButtonPressMask | ButtonReleaseMask;
        !           119:        /* pfont = XLoadQueryFont(dpy, "fixed"); */
        !           120: 
        !           121:        /* 
        !           122:         * go get the mouse as soon as you can 
        !           123:         */
        !           124: 
        !           125:        while (1) {
        !           126:                int res;
        !           127:                if ((res = XGrabPointer (dpy, RootWindow(dpy, scr), FALSE, events, 
        !           128:                  GrabModeAsync, GrabModeAsync, None, ul, CurrentTime )) == 
        !           129:                    GrabSuccess)
        !           130:                  break;
        !           131:                sleep (1);
        !           132:        }
        !           133:        nz = strlen(name);              /* compute number of characters */
        !           134:        text = (char *)malloc( nz + 11 );
        !           135:        (void) strcpy(text, name);
        !           136:        (void) strcat(text, ": 000x000");
        !           137:        nz += 9;
        !           138:        popw = XTextWidth (pfont, text, nz) + 2 * IBW;
        !           139:        poph = pfont->ascent+pfont->descent + 2 * IBW;
        !           140: 
        !           141:        /* pfore = WhitePixel(dpy, scr);
        !           142:         * pback = BlackPixel(dpy, scr);
        !           143:          * xgc.foreground = pfore;
        !           144:          * xgc.background = pback;
        !           145:         * xgc.font = pfont->fid;
        !           146:         * popGC = XCreateGC(dpy, RootWindow(dpy, scr),
        !           147:         *    GCForeground+GCBackground+GCFont, &xgc);
        !           148:         * xgc.function = GXinvert;
        !           149:         * xgc.subwindow_mode = IncludeInferiors;
        !           150:         * invertGC = XCreateGC(dpy, RootWindow(dpy, scr),
        !           151:         *   GCForeground+GCBackground+GCFont+GCFunction+GCSubwindowMode, &xgc);
        !           152:         */
        !           153: 
        !           154:        pop = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), 
        !           155:                0, 0, popw, poph, BW, pback, pback);
        !           156:        XMapWindow (dpy, pop);
        !           157: 
        !           158:        if (hints->flags&PMinSize) {
        !           159:          minwidth = hints->min_width;
        !           160:          minheight = hints->min_height;
        !           161:        } else {
        !           162:          minwidth = 0;
        !           163:          minheight = 0;
        !           164:        }
        !           165:        if (hints->flags&PMaxSize) {
        !           166:          maxwidth = max(hints->max_width, minwidth);
        !           167:          maxheight = max(hints->max_height, minheight);
        !           168:        } else {
        !           169:          maxwidth = DisplayWidth(dpy, scr);
        !           170:          maxheight = DisplayHeight(dpy, scr);
        !           171:        }
        !           172:        if (hints->flags&PResizeInc) {
        !           173:          xinc = hints->width_inc;
        !           174:          yinc = hints->height_inc;
        !           175:        } else {
        !           176:          xinc = 1;
        !           177:          yinc = 1;
        !           178:        }
        !           179:        if (hints->flags&PSize || hints->flags&USSize) {
        !           180:          defwidth = hints->width;
        !           181:          defheight = hints->height;
        !           182:        } else if (hints->flags&PMinSize) {
        !           183:          defwidth = hints->min_width;
        !           184:          defheight = hints->min_height;
        !           185:        } else if (hints->flags&PMaxSize) {
        !           186:          defwidth = hints->max_width;
        !           187:          defheight = hints->max_height;
        !           188:         } else {
        !           189:                long dummy;
        !           190:                XGetGeometry(dpy, window, &dummy, &dummy, &dummy,
        !           191:                             &defwidth, &defheight, &dummy, &dummy);
        !           192:        }
        !           193: 
        !           194:       /* until there are better WM_HINTS, we'll assume that the client's
        !           195:        * minimum width and height are the appropriate offsets to subtract
        !           196:        * when resizing with an explicit resize increment.
        !           197:        */
        !           198:       if (hints->flags&PMinSize && hints->flags&PResizeInc) {
        !           199:          width_offset = hints->min_width;
        !           200:          height_offset = hints->min_height;
        !           201:       } else
        !           202:          width_offset = height_offset = 0;
        !           203:        
        !           204: 
        !           205:        XQueryPointer (dpy, RootWindow(dpy, scr), &root, &subw, 
        !           206:          &rootx, &rooty, &x1, &y1, &mask);
        !           207:        hsize = minwidth; 
        !           208:        vsize = minheight;
        !           209:        x2 = x1+hsize; 
        !           210:        y2 = y1+vsize;
        !           211: 
        !           212:        while (stop == FALSE) {
        !           213:            if ( (xb != max (x1, x2)) || (yb != max (y1, y2))
        !           214:                ||(xa != min (x1, x2)) || (ya != min (y1, y2)) ) {
        !           215:                xa = min (x1, x2);
        !           216:                ya = min (y1, y2);
        !           217:                xb = max (x1, x2);
        !           218:                yb = max (y1, y2);
        !           219:                for ( i = 0; i < PCOUNT; i += 4) {
        !           220:                     box[i].x = xa; box[i].y = ya;
        !           221:                     if (i+1 == PCOUNT) break;
        !           222:                     box[i+1].x = xb; box[i+1].y = ya;
        !           223:                     box[i+2].x = xb; box[i+2].y = yb;
        !           224:                     box[i+3].x = xa; box[i+3].y = yb;
        !           225:                 }
        !           226:                doit = TRUE;
        !           227:            }
        !           228:            if (changed) {
        !           229:                int Hsize = (hsize - width_offset) / xinc;
        !           230:                int Vsize = (vsize - height_offset) / yinc;
        !           231:                int pos = 3;
        !           232: 
        !           233:                changed = FALSE;
        !           234:                text[nz - 7] = (Hsize>99) ? (Hsize / 100 + zero)        : ' ';
        !           235:                text[nz - 6] = (Hsize>9)  ? ((Hsize / 10) % 10 + zero)  : ' ';
        !           236:                text[nz - 5] = Hsize % 10 + zero;
        !           237:                if (Vsize>99) text[nz - pos--] = Vsize / 100 + zero;
        !           238:                if (Vsize>9)  text[nz - pos--] = (Vsize / 10) % 10 + zero;
        !           239:                text[nz - pos--]     = Vsize % 10 + zero;
        !           240:                while (pos>0) text[nz - pos--] = ' ';
        !           241:                XDrawImageString(dpy, pop, popGC, IBW, IBW+pfont->ascent,
        !           242:                        text, nz);
        !           243:            }
        !           244:            if (doit) {
        !           245:                XDrawLines(dpy, RootWindow(dpy, scr), invertGC, box, PCOUNT, 
        !           246:                  CoordModeOrigin);
        !           247:            }
        !           248:             if (XPending(dpy) &&
        !           249:                XCheckMaskEvent(dpy, ButtonPressMask|ButtonReleaseMask, &e)) {
        !           250:                 if ((chosen < 0) && (e.type == ButtonPress)) {
        !           251:                        x1 = x2 = ((XButtonEvent *)&e)->x;
        !           252:                         y1 = y2 = ((XButtonEvent *)&e)->y;
        !           253:                         chosen = ((XButtonEvent *)&e)->button;
        !           254:                        if (chosen == Button2)
        !           255:                                change_cursor = TRUE;
        !           256:                 }
        !           257:                 else if ((e.type == ButtonRelease) &&
        !           258:                         ((((XButtonEvent *)&e)->button) == chosen)) {
        !           259:                        x2 = ((XButtonEvent *)&e)->x;
        !           260:                        y2 = ((XButtonEvent *)&e)->y;
        !           261:                         stop = TRUE;
        !           262:                 }
        !           263:                else
        !           264:                         XQueryPointer (dpy, RootWindow(dpy, scr), &root, 
        !           265:                          &subw, &rootx, &rooty, &x2, &y2, &mask);
        !           266:             }
        !           267:             else        XQueryPointer (dpy, RootWindow(dpy, scr), &root, 
        !           268:                          &subw, &rootx, &rooty, &x2, &y2, &mask);
        !           269:            if (change_cursor) {
        !           270:                 if ((x2 >= x1) && (y2 >= y1) &&
        !           271:                     current_cursor != lr) {
        !           272:                     XChangeActivePointerGrab (dpy, events, lr, CurrentTime );
        !           273:                     current_cursor = lr;
        !           274:                }
        !           275:                 else if ((x2 >= x1) && (y2 < y1) &&
        !           276:                          current_cursor != ur) {
        !           277:                     XChangeActivePointerGrab (dpy, events, ur, CurrentTime );
        !           278:                     current_cursor = ur;
        !           279:                 }
        !           280:                 else if ((x2 < x1) && (y2 >= y1) &&
        !           281:                          current_cursor != ll) {
        !           282:                     XChangeActivePointerGrab (dpy, events, ll, CurrentTime );
        !           283:                     current_cursor = ll;
        !           284:                 }
        !           285:                 else if ((x2 < x1) && (y2 < y1) &&
        !           286:                          (current_cursor != ul)) {
        !           287:                     XChangeActivePointerGrab (dpy, events, ul, CurrentTime );
        !           288:                     current_cursor = ul;
        !           289:                 }
        !           290:            }
        !           291:            if (chosen != Button2) {
        !           292:                x1 = x2;
        !           293:                y1 = y2;
        !           294:                if (chosen >= 0) {
        !           295:                        x2 = defwidth;
        !           296:                        if (chosen == Button1)
        !           297:                                y2 = defheight;
        !           298:                        else
        !           299:                                y2 = (DisplayHeight(dpy, scr) - y1);
        !           300:                        x2 = x1 + x2;
        !           301:                        y2 = y1 + y2;
        !           302:                }
        !           303:            }
        !           304: 
        !           305:            dx = max(min(abs (x2 - x1), maxwidth), minwidth);
        !           306:            dx = makemult(dx-minwidth, xinc)+minwidth; 
        !           307:            dy = max(min(abs(y2 - y1), maxheight), minheight);
        !           308:            dy = makemult(dy-minheight, yinc)+minheight; 
        !           309:            
        !           310:            if (hints->flags & PAspect) {
        !           311:                 if ((dx * hints->max_aspect.y > dy * hints->max_aspect.x)) {
        !           312:                   delta = makemult( 
        !           313:                       (dx*hints->max_aspect.y/hints->max_aspect.x) - dy, 
        !           314:                       yinc); 
        !           315:                   if ((dy+delta) <= maxheight)  dy += delta;
        !           316:                   else {
        !           317:                     delta = makemult(
        !           318:                        dx - hints->max_aspect.x * dy/hints->max_aspect.y, 
        !           319:                        xinc);
        !           320:                     if ((dx-delta) >= minwidth) dx -= delta;
        !           321:                   }
        !           322:                }
        !           323:                 if (dx * hints->min_aspect.y < dy * hints->min_aspect.x) {
        !           324:                   delta = makemult( 
        !           325:                        (hints->min_aspect.x * dy/hints->min_aspect.y) - dx, 
        !           326:                        xinc);
        !           327:                   if (dx+delta <= maxwidth) dx += delta;
        !           328:                   else {
        !           329:                     delta = makemult(
        !           330:                       dy - (dx*hints->min_aspect.y / hints->min_aspect.x), 
        !           331:                       yinc); 
        !           332:                     if ((dy-delta) >= minheight) dy -= delta;
        !           333:                   }
        !           334:                }
        !           335:                  
        !           336:            }
        !           337: 
        !           338:            if (dx != hsize) {
        !           339:                hsize = dx;
        !           340:                changed = TRUE;
        !           341:            }
        !           342:            if (dy != vsize) {
        !           343:                vsize = dy;
        !           344:                changed = TRUE;
        !           345:            }
        !           346:            if (x2 < x1)
        !           347:                x2 = x1 - dx;
        !           348:            else
        !           349:                x2 = x1 + dx;
        !           350: 
        !           351:            if (y2 < y1)
        !           352:                y2 = y1 - dy;
        !           353:            else
        !           354:                y2 = y1 + dy;
        !           355:        }
        !           356:        XUngrabPointer(dpy, CurrentTime);
        !           357: 
        !           358:        XDestroyWindow (dpy, pop);
        !           359:        /* XFreeFont(dpy, pfont); */
        !           360:        XFreeCursor (dpy, ur);
        !           361:        XFreeCursor (dpy, ul);
        !           362:        XFreeCursor (dpy, lr);
        !           363:        XFreeCursor (dpy, ll);
        !           364:        free(name);
        !           365:        free(text);
        !           366:        *x = min(x1, x2);
        !           367:        *y = min(y1, y2);
        !           368:        *width = hsize;
        !           369:        *height = vsize;
        !           370:        XSync(dpy, False);
        !           371:        }

unix.superglobalmegacorp.com

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