1: #include <X/mit-copyright.h> 2: 3: /* Copyright Massachusetts Institute of Technology 1984, 1985 */ 4: 5: #include "gedit.h" 6: #include <X/Xlib.h> 7: 8: #ifndef lint 9: static char *rcsid_gx_c = "$Header: gx.c,v 10.6 86/02/01 16:19:07 tony Rel $"; 10: #endif lint 11: 12: char *index(); 13: 14: static short crbits[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 15: 16: Window w, trw; 17: Font font; 18: int forepix, backpix, invplanes; 19: 20: char mousechanged; 21: short mousex, mousey; 22: 23: short wminx; /* lower left of display window */ 24: short wminy; 25: short wmaxx; /* upper right of display window */ 26: short wmaxy; 27: short chrwid; 28: short chrhgt; 29: 30: /* command dispatch per key */ 31: fptr dispatch[256]; 32: 33: /* used to fill in dispatch upon initialization */ 34: int mleft(),newlabel(),stop(),delobj(),editobj(),mright(),toggle(); 35: int quit(),instantiate(),newline(),redisplay(),mdown(),neworg(); 36: int mup(),rotateobj(),selobj(),multiplier(),setwindow(),scale(); 37: int letgo(),rescale(),newin(),newout(),snap(),curup(),curdown(); 38: int home(),setcolor(),lastgo(),angle(),Help(); 39: int editlast(), scaleup(), scaledn(), fixwindow(); 40: 41: struct icmd { char *keys; fptr func; } cmds[] = { 42: "[", scaleup, 43: "]", scaledn, 44: "Aa\001", angle, 45: "Bb\002Hh\010", mleft, 46: "Cc", newlabel, 47: "\003\021", stop, 48: "Dd\004", delobj, 49: "Ee\005", editobj, 50: "Ff\006", mright, 51: "Gg", toggle, 52: "\007", quit, 53: "Hh", Help, 54: "Ii", instantiate, 55: "Ll", newline, 56: "Mm", lastgo, 57: "\014", redisplay, 58: "Nn\016", mdown, 59: "\017", neworg, 60: "Pp\020", mup, 61: "Rr\022", rotateobj, 62: "Ss\023", selobj, 63: "Uu\025", multiplier, 64: "Ww\027", setwindow, 65: "Xx\030", scale, 66: "Zz\032 ", letgo, 67: "^", editlast, 68: "*", rescale, 69: "<", newin, 70: ">", newout, 71: "!", snap, 72: "+", curup, 73: "-", curdown, 74: "@", home, 75: "\031", fixwindow, 76: NULL, NULL 77: }; 78: 79: /* see if there is input ready from the user */ 80: UserReady() 81: { XEvent ev; 82: int n, x, y; 83: Window sub; 84: 85: while (XPending()) { 86: XPeekEvent(&ev); 87: switch (ev.type) { 88: case MouseMoved: 89: mousechanged = 1; 90: XNextEvent(&ev); 91: XUpdateMouse(w, &x, &y, &sub); 92: mousex = x; 93: mousey = y; 94: return(1); 95: case ButtonPressed: 96: return(1); 97: case KeyPressed: 98: XLookupMapping((XKeyPressedEvent *)(&ev), &n); 99: if (n == 1) return (1); 100: XNextEvent(&ev); 101: break; 102: case ExposeRegion: 103: case ExposeWindow: 104: return(1); 105: } 106: } 107: return(0); 108: } 109: 110: /* get character from user */ 111: UserChar() 112: { XEvent ev; 113: int n; 114: char *str; 115: 116: while (1) { 117: XNextEvent(&ev); 118: switch (ev.type) { 119: case ButtonPressed: 120: n = ((XButtonPressedEvent *) (&ev))->detail & ValueMask; 121: switch (n) { 122: case LeftButton: 123: return('l'); 124: case MiddleButton: 125: return('z'); 126: case RightButton: 127: return('s'); 128: } 129: break; 130: case KeyPressed: 131: str = XLookupMapping((XKeyPressedEvent *)(&ev), &n); 132: if (n == 1) return (*str); 133: break; 134: case ExposeRegion: 135: return('\014'); 136: case ExposeWindow: 137: if (((XExposeWindowEvent *) (&ev))->width == wmaxx && 138: ((XExposeWindowEvent *) (&ev))->height == wmaxy) 139: return('\014'); 140: wmaxx = ((XExposeWindowEvent *) (&ev))->width; 141: wmaxy = ((XExposeWindowEvent *) (&ev))->height; 142: XChangeWindow(trw, wmaxx, wmaxy - (chrhgt << 1)); 143: return('\031'); 144: } 145: } 146: } 147: 148: 149: /* display grid */ 150: drawgrid(x,y,incrx,incry) 151: { int i; 152: Vertex vert[2]; 153: 154: if (incrx <= 16) { 155: vert[0].x = x; 156: vert[0].flags = 0; 157: vert[1].x = wmaxx; 158: vert[1].flags = 0; 159: while (y > 0) { 160: vert[0].y = y; 161: vert[1].y = y; 162: XDrawDashed(trw, vert, 2, 1, 1, forepix, 163: XMakePattern(1, incrx, 1), GXcopy, AllPlanes); 164: y -= incry; 165: } 166: XClearVertexFlag(); 167: } else if (incry <= 16) { 168: vert[0].y = y; 169: vert[0].flags = 0; 170: vert[1].y = 0; 171: vert[1].flags = 0; 172: while (x < wmaxx) { 173: vert[0].x = x; 174: vert[1].x = x; 175: XDrawDashed(trw, vert, 2, 1, 1, forepix, 176: XMakePattern(1, incry, 1), GXcopy, AllPlanes); 177: x += incrx; 178: } 179: XClearVertexFlag(); 180: } else { 181: while (x < wmaxx) { 182: for (i = y; i > 0; i -= incry) { 183: XPixSet(trw, x, i, 1, 1, forepix); 184: } 185: x += incrx; 186: } 187: } 188: } 189: 190: /* set up display adaptor for 80x25 alpha color, release keyboard */ 191: gexit() 192: { 193: } 194: 195: track() 196: { int x,y; 197: int code = 0; 198: 199: mousechanged = 0; 200: 201: x = mousex * cur_state.dscale; 202: y = (wmaxy - mousey) * cur_state.dscale; 203: x += cur_state.worgx; 204: y += cur_state.worgy; 205: 206: if (x!=cur_state.curx || y!=cur_state.cury) { 207: if (x >= cur_state.wmaxx) 208: x = cur_state.wmaxx - 1; 209: else if (x < cur_state.worgx) 210: x = cur_state.worgx; 211: if (y >= cur_state.wmaxy) 212: y = cur_state.wmaxy - 1; 213: else if (y < cur_state.worgy) 214: y = cur_state.worgy; 215: cur_state.curx = x; 216: cur_state.cury = y; 217: } 218: 219: return(code); 220: } 221: 222: remouse(x, y, doit) 223: { 224: if (x >= cur_state.wmaxx || x < cur_state.worgx || 225: y >= cur_state.wmaxy || y < cur_state.worgy) { 226: cur_state.curx = x; 227: cur_state.cury = y; 228: return(RECENTER); 229: } 230: if (doit || (x != cur_state.curx || y != cur_state.cury)) { 231: cur_state.curx = x; 232: cur_state.cury = y; 233: x -= cur_state.worgx; 234: y -= cur_state.worgy; 235: x /= cur_state.dscale; 236: y /= cur_state.dscale; 237: y = wmaxy - y; 238: if (x != mousex || y != mousey) { 239: XCondWarpMouse(w, x, y, w, mousex, mousey, 1, 1); 240: /* XWarpMouse(w, x, y); */ 241: XFlush(); 242: } 243: } 244: return(0); 245: } 246: 247: /* set up display adaptor for graphics and initialize keyboard */ 248: char *gentry(argc,argv) 249: int argc; 250: char **argv; 251: { char *prog; 252: char *fname = NULL; 253: register struct icmd *p; 254: register char *q; 255: WindowInfo winfo; 256: FontInfo finfo; 257: char *fore_color, *back_color, *brdr_color, *font_name; 258: char *geometry = NULL; 259: char *display = NULL; 260: int reverse = 0; 261: Color cdef; 262: char def[32]; 263: OpaqueFrame frame; 264: 265: /* fill in command dispatch table */ 266: for (p = cmds; p->keys != NULL; p++) 267: for (q = p->keys; *q; q++) dispatch[*q & 0xFF] = p->func; 268: 269: prog = *argv; 270: if ((q = XGetDefault(prog, "ReverseVideo")) && 271: strcmp(q, "on") == 0) 272: reverse = 1; 273: frame.bdrwidth = 2; 274: if (q = XGetDefault(prog, "BorderWidth")) 275: frame.bdrwidth = atoi(q); 276: fore_color = XGetDefault(prog, "ForeGround"); 277: back_color = XGetDefault(prog, "BackGround"); 278: brdr_color = XGetDefault(prog, "Border"); 279: font_name = XGetDefault(prog, "BodyFont"); 280: for (argv++; --argc; argv++) { 281: if (!strcmp(*argv, "-rv")) { 282: reverse = 1; 283: } else if (!strcmp(*argv, "-fg") && argc) { 284: argv++; 285: argc--; 286: fore_color = *argv; 287: } else if (!strcmp(*argv, "-bg") && argc) { 288: argv++; 289: argc--; 290: back_color = *argv; 291: } else if (!strcmp(*argv, "-bd") && argc) { 292: argv++; 293: argc--; 294: brdr_color = *argv; 295: } else if (!strcmp(*argv, "-fn") && argc) { 296: argv++; 297: argc--; 298: font_name = *argv; 299: } else if (**argv == '=') { 300: geometry = *argv; 301: } else if (index(*argv, ':')) { 302: display = *argv; 303: } else if (**argv == '-' || fname != NULL) { 304: printf("usage: xgedit [-rv] [-fn <font>] [-fg <color>] [-bg <color>] [-bd <color>] [=<geometry>] [host:display] [file]\n"); 305: exit(1); 306: } else { 307: fname = *argv; 308: } 309: } 310: if (!XOpenDisplay(display)) { 311: fprintf(stderr, "could not connect to display\n"); 312: exit(1); 313: } 314: if (reverse) { 315: forepix = WhitePixel; 316: backpix = BlackPixel; 317: frame.background = BlackPixmap; 318: frame.border = WhitePixmap; 319: } else { 320: forepix = BlackPixel; 321: backpix = WhitePixel; 322: frame.background = WhitePixmap; 323: frame.border = BlackPixmap; 324: } 325: if (DisplayCells() > 2) { 326: if (fore_color && XParseColor(fore_color, &cdef) && 327: XGetHardwareColor(&cdef)) 328: forepix = cdef.pixel; 329: if (back_color && XParseColor(back_color, &cdef) && 330: XGetHardwareColor(&cdef)) 331: frame.background = XMakeTile(backpix = cdef.pixel); 332: if (brdr_color && XParseColor(brdr_color, &cdef) && 333: XGetHardwareColor(&cdef)) 334: frame.border = XMakeTile(cdef.pixel); 335: } 336: invplanes = forepix ^ backpix; 337: if (font_name == NULL) font_name = "8x13"; 338: font = XGetFont(font_name); 339: if (!font) { 340: fprintf(stderr, "no such font: %s\n", font_name); 341: exit(1); 342: } 343: XQueryFont(font, &finfo); 344: XQueryWindow(RootWindow, &winfo); 345: chrwid = finfo.width; 346: chrhgt = finfo.height; 347: frame.x = 1; 348: frame.y = 1; 349: frame.width = 80 * chrwid; 350: if (frame.width + (frame.bdrwidth<<1) > winfo.width) 351: frame.width = winfo.width - (frame.bdrwidth<<1); 352: frame.height = 25 * chrhgt; 353: if (frame.height + (frame.bdrwidth<<1) > winfo.height) 354: frame.height = winfo.height - (frame.bdrwidth<<1); 355: sprintf(def, "=%dx%d+1+1", frame.width, frame.height); 356: wminx = 0; 357: wminy = 2*chrhgt; 358: w = XCreate(prog, prog, geometry, def, &frame, 5 * chrwid, wminy + 5 * chrhgt); 359: wmaxx = frame.width; 360: wmaxy = frame.height; 361: trw = XCreateTransparency(w, 0, 0, wmaxx, wmaxy - (chrhgt << 1)); 362: XMapWindow(trw); 363: XDefineCursor(w, XCreateCursor(16, 16, crbits, crbits, 7, 7, 364: backpix, forepix, GXnoop)); 365: XSetResizeHint(w, 1, wminy + 1, 1, 1); 366: XMapWindow(w); 367: XSelectInput(w, KeyPressed|ButtonPressed|MouseMoved|ExposeRegion); 368: mousechanged = 0; 369: return(fname); 370: } 371: 372: Beep() 373: { XFeep(0); 374: } 375: 376: /* give status info on second to last line */ 377: banner() 378: { char temp[100]; 379: 380: if (cur_state.curobj != NULL) 381: sprintf(temp,"XGEDIT %d:%d %c %s", 382: cur_state.mscale,cur_state.dscale, 383: cur_state.curobj->modified ? '*':' ', 384: cur_state.curobj->name); 385: else sprintf(temp,"XGEDIT %d:%d", 386: cur_state.mscale,cur_state.dscale); 387: 388: XPixSet(w, 0, wmaxy - (chrhgt << 1), wmaxx, chrhgt, backpix); 389: 390: disp_str(temp, 0, chrhgt, 1, HIGHLIGHT, 1); 391: } 392: 393: /* display a string at the specified position, return lenth */ 394: disp_str(s,x,y,reverse,xorflag,info) 395: char *s; 396: { int len; 397: len = strlen(s); 398: if (reverse) 399: XText(info ? w : trw, x, wmaxy - y - chrhgt, s, len, font, 400: backpix, forepix); 401: else 402: XTextMaskPad(info ? w : trw, x, wmaxy - y - chrhgt, s, len, font, 403: 0, 0, forepix, xorflag ? GXinvert : GXcopy, 404: xorflag ? invplanes: AllPlanes); 405: return(len); 406: } 407: 408: /* display a character at the specified position */ 409: disp_char(ch,x,y,reverse,xorflag,info) 410: { char c = ch; 411: if (reverse) 412: XText(info ? w : trw, x, wmaxy - y - chrhgt, &c, 1, font, 413: backpix, forepix); 414: else 415: XTextMaskPad(info ? w : trw, x, wmaxy - y - chrhgt, &c, 1, font, 416: 0, 0, forepix, xorflag ? GXinvert : GXcopy, 417: xorflag ? invplanes : AllPlanes); 418: } 419: 420: /* Update display, cursor */ 421: DpyUp(tflag) 422: { XEvent ev; 423: 424: if (tflag) tcurxor(); 425: dcurxor(); 426: do { 427: XPeekEvent(&ev); 428: } while (UserReady() == 0); 429: if (tflag) tcurxor(); 430: dcurxor(); 431: } 432: 433: /* xor the text cursor */ 434: tcurxor() 435: { XPixFill(w, incol*chrwid, wmaxy - chrhgt, chrwid, chrhgt, forepix, (Bitmap) NULL, 436: GXinvert, invplanes); 437: } 438: 439: clearprompt() 440: { incol = 0; 441: XPixSet(w, 0, wmaxy - chrhgt, wmaxx, chrhgt, backpix); 442: } 443: 444: clearscreen() 445: { XClear(w); 446: banner(); 447: clearprompt(); 448: } 449: 450: static int lastx, lasty; 451: static int lastflag; 452: static int lastcnt = 1000; 453: 454: /* draw a vector from <FromX,FromY> to <ToX,ToY> */ 455: line(FromX,FromY,ToX,ToY,xorflag) 456: { Vertex vert[2]; 457: vert[0].x = FromX; 458: vert[0].y = wmaxy - FromY; 459: vert[0].flags = VertexDontDraw; 460: vert[1].x = ToX; 461: vert[1].y = wmaxy - ToY; 462: vert[1].flags = VertexDrawLastPoint; 463: if (xorflag == lastflag && lastcnt < 250 && 464: ((FromX == lastx && FromY == lasty && 465: XAppendVertex(&vert[1], 1) > 0) 466: || XAppendVertex(vert, 2) > 0)) { 467: lastx = ToX; 468: lasty = ToY; 469: lastcnt++; 470: return; 471: } 472: lastx = ToX; 473: lasty = ToY; 474: lastflag = xorflag; 475: lastcnt = 1; 476: XDraw(trw, vert, 2, 1, 1, forepix, xorflag ? GXinvert : GXcopy, 477: xorflag ? invplanes : AllPlanes); 478: }