1: #include <X/mit-copyright.h> 2: 3: /* $Header: XCreateTerm.c,v 10.10 86/02/01 15:31:14 tony Rel $ */ 4: /* Copyright 1985, Massachusetts Institute of Technology */ 5: /* stolen from CLU routine x_tcons, redone by J. Gettys */ 6: 7: #include "XlibInternal.h" 8: #include <stdio.h> 9: #include <strings.h> 10: #define TRUE 1 11: #define FALSE 0 12: #define max(a,b) ( (a) > (b) ? (a) : (b) ) 13: #define min(a,b) ( (a) > (b) ? (b) : (a) ) 14: #define abs(a) ( (a) > 0 ? (a) : -(a)) 15: 16: #define DCOUNT 2 17: #define VCOUNT 1 + (4 * 2 * DCOUNT) 18: #define FCOUNT 1 + 4 19: 20: #include "../cursors/cross.cursor" 21: #include "../cursors/cross_mask.cursor" 22: 23: Window XCreateTerm(name, prog, geometry, def, frame, minwidth, minheight, 24: xadder, yadder, cwidth, cheight, f, fwidth, fheight) 25: char *name, *prog; /* prompt string and name of program */ 26: register OpaqueFrame *frame; /* frame for resulting window */ 27: int minwidth, minheight; /* this time in units of characters*/ 28: int *cwidth, *cheight; /* returns the size of the window */ 29: FontInfo *f; /* major bodyfont of the window */ 30: int fwidth, fheight; /* width and height of increments */ 31: int xadder, yadder; /* add is size of internal padding */ 32: { 33: int pr; /* parse geometry result */ 34: int defwidth, defheight; /* frame from parse... */ 35: int defx, defy; 36: FontInfo *pfont; 37: int pfore, pback; /* prompt foreground and background */ 38: int bpix; 39: int mfore; /* mouse cursor colors */ 40: int mback; /* background color for mouse */ 41: int clip = 0; /* clip window to screen */ 42: int freeze = 0; /* freeze server */ 43: Color cdef; /* color structure */ 44: int events; /* what events we want. */ 45: int popw, poph; /* width and height of prompt window*/ 46: char text[64]; /* text for prompt string */ 47: int zero = '0'; /* zero offset for char conversion */ 48: int x1, y1; /* location of mouse */ 49: int x2, y2; /* other corner of box */ 50: XButtonEvent e; /* someplace to put the event */ 51: Cursor cr; /* cursor for rubber banding */ 52: Window pop; /* pop up prompt window */ 53: Pixmap save = 0; /* saved pixmap */ 54: Pixmap backmap, bdrmap; /* background and border pixmaps*/ 55: Vertex box[VCOUNT]; /* vertex list for box */ 56: Window subw; /* window cursor was in (not used) */ 57: register int i; /* ye olde indexe variabel */ 58: int count = VCOUNT; /* vertex count */ 59: int nz; /* count where zeros are */ 60: int xadd, yadd; 61: int hsize, vsize; 62: char *opt; /* option back from XGetdefault */ 63: int ibw = 0; /* internal border width */ 64: int pbw = 0; /* prompt window border width */ 65: int bwidth = frame->bdrwidth; /* border width of final window */ 66: int xa = -1, ya = -1, xb = -1, yb = -1; 67: int chosen = -1; 68: int stop = FALSE; 69: int changed = TRUE; 70: int doit = TRUE; 71: int xmindim, ymindim; 72: int d; 73: 74: pr = XGeometry(geometry, def, bwidth, fwidth, fheight, xadder, yadder, 75: &defx, &defy, &defwidth, &defheight); 76: defwidth = max(defwidth, minwidth); 77: defheight = max(defheight, minheight); 78: 79: /* "do the right thing" if the user asked for placement */ 80: if ((pr & XValue) || (pr & YValue)) { 81: *cwidth = defwidth; 82: *cheight = defheight; 83: frame->width = defwidth * fwidth + xadder; 84: frame->height = defheight * fheight + yadder; 85: frame->x = defx; 86: frame->y = defy; 87: goto makeit; 88: } 89: if ((opt = XGetDefault(prog, "MakeWindow.BodyFont")) == NULL) 90: pfont = f; 91: else 92: if ((pfont = XOpenFont(opt)) == NULL) pfont = f; 93: 94: pfore = WhitePixel; 95: pback = BlackPixel; 96: 97: if ((opt = XGetDefault(prog, "MakeWindow.ReverseVideo")) != NULL) 98: if (strcmp(opt, "on") == 0) { 99: pfore = BlackPixel; 100: pback = WhitePixel; 101: } 102: bpix = pback; 103: mfore = pback; 104: mback = pfore; 105: 106: if ((opt = XGetDefault(prog, "MakeWindow.BorderWidth")) != NULL) 107: pbw = atoi (opt); 108: 109: if ((opt = XGetDefault(prog, "MakeWindow.InternalBorder")) != NULL) 110: ibw = atoi (opt); 111: 112: if ((opt = XGetDefault(prog, "MakeWindow.Freeze")) != NULL) 113: if (strcmp (opt, "on") == 0) freeze = 1; 114: 115: if ((opt = XGetDefault(prog, "MakeWindow.ClipToScreen")) != NULL) 116: if (strcmp (opt, "on") == 0) clip = 1; 117: 118: if (DisplayPlanes() > 2) { /* on color display, do color stuff */ 119: 120: if ((opt = XGetDefault(prog,"MakeWindow.Foreground")) != NULL) 121: if (XParseColor(opt, &cdef) && XGetHardwareColor(&cdef)) 122: pfore = cdef.pixel; 123: 124: if ((opt = XGetDefault(prog,"MakeWindow.Background")) != NULL) 125: if (XParseColor(opt, &cdef) && XGetHardwareColor(&cdef)) 126: pback = cdef.pixel; 127: 128: if ((opt = XGetDefault(prog,"MakeWindow.Border")) != NULL) 129: if (XParseColor(opt, &cdef) && XGetHardwareColor(&cdef)) 130: bpix = cdef.pixel; 131: 132: if ((opt = XGetDefault(prog,"MakeWindow.Mouse")) != NULL) 133: if (XParseColor(opt, &cdef) && XGetHardwareColor(&cdef)) 134: mfore = cdef.pixel; 135: 136: if ((opt = XGetDefault(prog,"MakeWindow.MouseMask")) != NULL) 137: if (XParseColor(opt, &cdef) && XGetHardwareColor(&cdef)) 138: mback = cdef.pixel; 139: } 140: cr = XCreateCursor (cross_width, cross_height, cross_bits, 141: cross_mask_bits, cross_x_hot, cross_y_hot, 142: mfore, mback, GXcopy); 143: 144: events = ButtonPressed | ButtonReleased; 145: 146: if (freeze) events |= MouseMoved; 147: 148: /* 149: * go get the mouse as soon as you can 150: */ 151: 152: while (1) { 153: if (XGrabMouse ( RootWindow, cr, events ) != 0) break; 154: sleep (1); 155: } 156: (void) strncpy(text, name, sizeof(text) - 10); 157: (void) strncat(text, ": 000x000", 9); 158: nz = strlen(name) + 8; /* compute number of characters */ 159: popw = XStringWidth (text, pfont, 0, 0) + 2 * ibw; 160: poph = pfont->height + 2 * ibw; 161: 162: if (freeze) { 163: XGrabServer(); 164: count = FCOUNT; 165: save = XPixmapSave (RootWindow, 0, 0, 166: popw + 2 * pbw, poph +2 * pbw); 167: } 168: 169: backmap = XMakeTile (pback); 170: bdrmap = XMakeTile (bpix); 171: 172: pop = XCreateWindow (RootWindow, 173: 0, 0, popw, poph, pbw, bdrmap, backmap); 174: XMapWindow (pop); 175: 176: xadd = fwidth / 2 - xadder; 177: yadd = fheight / 2 - yadder; 178: 179: XQueryMouse (RootWindow, &x1, &y1, &subw); 180: 181: x2 = x1 + minwidth * fwidth + xadder + 2 * bwidth - 1; 182: y2 = y1 + minheight * fheight + yadder + 2 * bwidth - 1; 183: hsize = minwidth; 184: vsize = minheight; 185: 186: 187: xmindim = xadder + 2 * bwidth; 188: ymindim = yadder + 2 * bwidth; 189: 190: while (stop == FALSE) { 191: if ( (xb != max (x1, x2)) || (yb != max (y1, y2)) 192: ||(xa != min (x1, x2)) || (ya != min (y1, y2)) ) { 193: if (freeze && !doit) { 194: XDraw (RootWindow, box, count, 1, 1, 0, GXinvert, 1); 195: } 196: xa = min (x1, x2); 197: ya = min (y1, y2); 198: xb = max (x1, x2); 199: yb = max (y1, y2); 200: for ( i = 0; i < count; i += 4) { 201: box[i].x = xa; box[i].y = ya; box[i].flags = 0; 202: if (i+1 == count) break; 203: box[i+1].x = xb; box[i+1].y = ya, box[i+1].flags = 0; 204: box[i+2].x = xb; box[i+2].y = yb, box[i+2].flags = 0; 205: box[i+3].x = xa; box[i+3].y = yb, box[i+3].flags = 0; 206: } 207: doit = TRUE; 208: } 209: if (changed) { 210: changed = FALSE; 211: text[nz - 6] = hsize / 100 + zero; 212: text[nz - 5] = (hsize / 10) % 10 + zero; 213: text[nz - 4] = hsize % 10 + zero; 214: text[nz - 2] = vsize / 100 + zero; 215: text[nz - 1] = (vsize / 10) % 10 + zero; 216: text[nz] = vsize % 10 + zero; 217: XText (pop, ibw, ibw, 218: text, strlen(text), pfont->id, pfore, pback); 219: } 220: if (doit) { 221: XDraw(RootWindow, box, count, 1, 1, 0, GXinvert, 1); 222: doit = !freeze; 223: } 224: if (freeze || XPending() ) { 225: XNextEvent(&e); 226: x2 = e.x; 227: y2 = e.y; 228: if ((chosen < 0) && (e.type == ButtonPressed)) { 229: x1 = x2; 230: y1 = y2; 231: chosen = e.detail & ValueMask; 232: } 233: else if ((e.type == ButtonReleased) && 234: ((e.detail & ValueMask) == chosen)) 235: stop = TRUE; 236: else 237: XQueryMouse(RootWindow, &x2, &y2, &subw); 238: } 239: else XQueryMouse(RootWindow, &x2, &y2, &subw); 240: if (chosen != MiddleButton) { 241: x1 = x2; 242: y1 = y2; 243: if (chosen >= 0) { 244: x2 = defwidth; 245: if (chosen == LeftButton) 246: y2 = defheight; 247: else 248: y2 = (DisplayHeight() - ymindim - cross_y_hot) 249: / fheight; 250: if (clip) { 251: x2 = min (max((DisplayWidth() - x1 - xmindim) / 252: fwidth, 0), x2); 253: y2 = min (max((DisplayHeight() - y1 - ymindim)/ 254: fheight, 0), y2); 255: } 256: x2 = x1 + x2 * fwidth + xadder - 1; 257: y2 = y1 + y2 * fheight + yadder - 1; 258: } 259: } 260: d = max (( abs (x2 - x1) + xadd) / fwidth, minwidth); 261: if (d != hsize) { 262: hsize = d; 263: changed = TRUE; 264: } 265: d = d * fwidth + xmindim - 1; 266: if (x2 < x1) 267: x2 = x1 - d; 268: else 269: x2 = x1 + d; 270: d = max ((abs(y2 - y1) + yadd) / fheight, minheight); 271: if (d != vsize) { 272: vsize = d; 273: changed = TRUE; 274: } 275: d = d * fheight + ymindim - 1; 276: if (y2 < y1) 277: y2 = y1 - d; 278: else 279: y2 = y1 + d; 280: } 281: if (freeze) XDraw (RootWindow, box, count, 1, 1, 0, GXinvert, 1); 282: XUngrabMouse(); 283: 284: if (save) { 285: XUnmapTransparent (pop); 286: XPixmapPut (RootWindow, 0, 0, 0, 0, 287: popw + 2 * pbw, poph + 2 * pbw, 288: save, GXcopy, AllPlanes); 289: XFreePixmap (save); 290: } 291: XDestroyWindow (pop); 292: if (freeze) XUngrabServer(); 293: if (pfont != f) XCloseFont (pfont); 294: XFreeCursor (cr); 295: XFreePixmap (backmap); 296: XFreePixmap (bdrmap); 297: frame->x = min(x1, x2); 298: frame->y = min(y1, y2); 299: frame->width = hsize * fwidth + xadder; 300: frame->height = vsize * fheight + yadder; 301: *cwidth = hsize; 302: *cheight = vsize; 303: makeit: XCreateWindows(RootWindow, frame, 1); 304: /* store default name of the window and set the resize hint */ 305: XStoreName(frame->self, name); 306: XSetResizeHint(frame->self, xadder, yadder, fwidth, fheight); 307: XSync(1); /* get rid of any extraneous events */ 308: return (frame->self); 309: }