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