Annotation of researchv9/X11/src/X.V11R1/clients/uwm/RubberBand.c, revision 1.1.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.