|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.