|
|
1.1 ! root 1: /* ! 2: * $Source: /@/orpheus/u1/X11/clients/xcalc/RCS/sr.c,v $ ! 3: * $Header: sr.c,v 1.2 87/09/11 01:50:21 newman Exp $ ! 4: */ ! 5: ! 6: #ifndef lint ! 7: static char *rcsid_sr_c = "$Header: sr.c,v 1.2 87/09/11 01:50:21 newman Exp $"; ! 8: #endif lint ! 9: ! 10: /* Slide Rule */ ! 11: ! 12: #include <stdio.h> ! 13: #include <math.h> ! 14: #include <strings.h> ! 15: #include <signal.h> ! 16: #include <X11/Xlib.h> ! 17: #include <X11/Xutil.h> ! 18: #include <X11/cursorfont.h> ! 19: #include <sys/time.h> ! 20: ! 21: ! 22: #define SLIDETOP 26 ! 23: #define SLIDEHIGH 38 ! 24: #define WIDTH 800 ! 25: #define HEIGHT 100 ! 26: #define START 70 ! 27: #define END 20 ! 28: #define LABEL 55 ! 29: #define MAXWIDTH 32766 ! 30: ! 31: #define FOFFSET 3 ! 32: #define MAJORH 10 ! 33: #define MIDDH 7 ! 34: #define MINORH 4 ! 35: #define HALVES 5 ! 36: #define FIFTHS 15 ! 37: #define TENTHS 40 ! 38: #define LABELFIFTH 41 ! 39: #define LABELTENTHS 200 ! 40: #define LABELSPACE 20 ! 41: ! 42: #define LSCALEH 2 ! 43: #define ASCALEH 16 ! 44: #define BSCALEH 0 ! 45: #define CISCALEH 14 ! 46: #define CSCALEH 28 ! 47: #define DSCALEH 66 ! 48: #define DISCALEH 84 ! 49: ! 50: extern Display *dpy; ! 51: Window slidewid,hairlwid,blackwid; ! 52: extern Window theWindow,dispwid; ! 53: extern XFontStruct *kfontinfo; ! 54: Font scalefont, sscalefont; ! 55: extern Pixmap stipplePix,regBorder,dimBorder,IconPix; ! 56: Pixmap slidePix = NULL; ! 57: Pixmap framePix = NULL; ! 58: extern Cursor arrow; ! 59: GC sgc, cgc; ! 60: int height,scalelen,width,fheight,foffset; ! 61: int xo,hx,xm; ! 62: extern int ForeColor,BackColor; ! 63: double log2; ! 64: extern short check_bits[]; ! 65: ! 66: ! 67: ! 68: /**************/ ! 69: do_sr(argc, argv, geom, border) ! 70: /**************/ ! 71: char **argv; ! 72: char *geom; ! 73: int border; ! 74: { ! 75: char def_geom[32]; ! 76: ! 77: XSizeHints szhint; ! 78: XEvent event; ! 79: XGCValues gcv; ! 80: ! 81: /* figure out sizes of keypad and display */ ! 82: ! 83: sscalefont = scalefont = kfontinfo->fid; ! 84: fheight = kfontinfo->max_bounds.ascent + FOFFSET; ! 85: foffset = kfontinfo->max_bounds.ascent; ! 86: ! 87: /* Open the main window. */ ! 88: width = WIDTH; ! 89: scalelen = width - START - END; ! 90: height = HEIGHT; ! 91: xo = -1; ! 92: hx = width/2; ! 93: log2 = log10(2.0); ! 94: ! 95: sprintf (def_geom, "=%dx%d+0-0", width, height); ! 96: if (geom == NULL) { ! 97: geom = (char *) malloc(24); ! 98: sprintf(geom, "=%dx%d", width, height); ! 99: } ! 100: ! 101: theWindow = XCreateSimpleWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)), ! 102: 0, 0, START+END+2, height, border, ! 103: ForeColor, BackColor); ! 104: ! 105: szhint.flags = PSize|PMinSize; ! 106: szhint.width = szhint.min_width = WIDTH; ! 107: szhint.height = szhint.min_height = HEIGHT; ! 108: XSetStandardProperties(dpy, theWindow, "Slide Rule", NULL, IconPix, ! 109: argv, argc, &szhint); ! 110: ! 111: blackwid = XCreateSimpleWindow(dpy, theWindow, ! 112: 0,SLIDETOP,WIDTH,SLIDEHIGH+2,0, ! 113: BackColor,ForeColor); ! 114: XSetWindowBackgroundPixmap(dpy, blackwid, stipplePix); ! 115: ! 116: slidewid = XCreateSimpleWindow(dpy, theWindow, ! 117: -1,SLIDETOP,WIDTH,SLIDEHIGH,1, ! 118: ForeColor, BackColor); ! 119: hairlwid = XCreateSimpleWindow(dpy, theWindow, ! 120: WIDTH/2,0,1,height,0, ! 121: BackColor, ForeColor); ! 122: dispwid = XCreateSimpleWindow(dpy, theWindow, ! 123: 0, 0, START-END, HEIGHT,1, ! 124: ForeColor, BackColor); ! 125: ! 126: gcv.foreground = ForeColor; ! 127: gcv.background = BackColor; ! 128: gcv.font = scalefont; ! 129: sgc = XCreateGC(dpy, theWindow, GCForeground|GCBackground|GCFont, &gcv); ! 130: gcv.foreground = BackColor; ! 131: gcv.background = ForeColor; ! 132: cgc = XCreateGC(dpy, theWindow, GCForeground|GCBackground|GCFont, &gcv); ! 133: ! 134: #define STDEVENTS ExposureMask|EnterWindowMask|LeaveWindowMask ! 135: #define BUTEVENTS ButtonPressMask|ButtonReleaseMask ! 136: #define MOVEVENTS Button1MotionMask|Button2MotionMask|Button3MotionMask ! 137: XSelectInput(dpy, theWindow, STDEVENTS|BUTEVENTS|MOVEVENTS); ! 138: XSelectInput(dpy, hairlwid, STDEVENTS); ! 139: XSelectInput(dpy, dispwid, STDEVENTS); ! 140: XSelectInput(dpy, slidewid, STDEVENTS|BUTEVENTS|MOVEVENTS); ! 141: XSelectInput(dpy, blackwid, STDEVENTS|BUTEVENTS); ! 142: ! 143: XMapWindow (dpy, theWindow); ! 144: XMapSubwindows(dpy, theWindow); ! 145: arrow=XCreateFontCursor(dpy, XC_hand2); ! 146: XDefineCursor (dpy, theWindow, arrow); ! 147: ! 148: ! 149: /**************** Main loop *****************/ ! 150: ! 151: while (1) { ! 152: Window wind,mwid; ! 153: int dummy, w; ! 154: ! 155: XNextEvent(dpy, &event); ! 156: ! 157: switch (event.type) { ! 158: ! 159: case Expose: { ! 160: XExposeEvent *exp_event = (XExposeEvent *) &event; ! 161: wind = exp_event->window; ! 162: ! 163: if (wind==theWindow) { ! 164: XGetGeometry(dpy, theWindow, &mwid, &dummy, &dummy, &w, &dummy, ! 165: &dummy, &dummy); ! 166: if (width != w) { ! 167: rescale(w); ! 168: break; ! 169: } ! 170: redrawframe(exp_event->x, exp_event->y, exp_event->width, ! 171: exp_event->height); ! 172: } else if (wind==slidewid) ! 173: redrawslide(exp_event->x, exp_event->y, exp_event->width, ! 174: exp_event->height); ! 175: else if (wind==hairlwid) ! 176: drawhairl(); ! 177: else if (wind==blackwid) ! 178: XClearWindow(dpy, blackwid, exp_event->x, exp_event->y, ! 179: exp_event->width, exp_event->height, 0); ! 180: else if (wind==dispwid) ! 181: drawnums(); ! 182: break; ! 183: } ! 184: case ButtonPress: { ! 185: XButtonPressedEvent *but_event = (XButtonPressedEvent *) &event; ! 186: ! 187: mwid = wind = but_event->window; ! 188: if (wind == slidewid || wind == blackwid) { ! 189: switch (but_event->button & 0xff) { ! 190: case Button1: ! 191: xo = (wind==slidewid?xo:0) + but_event->x - START; ! 192: break; ! 193: case Button2: ! 194: if (but_event->state & ShiftMask) ! 195: exit(0); ! 196: if (wind == slidewid) ! 197: xm = but_event->x; ! 198: break; ! 199: case Button3: ! 200: if (but_event->state & ShiftMask) ! 201: exit(0); ! 202: xo = (wind==slidewid?xo:0) + but_event->x + END - width; ! 203: break; ! 204: } ! 205: XMoveWindow(dpy, slidewid, xo - 1, SLIDETOP); ! 206: drawnums(); ! 207: break; ! 208: } ! 209: if (wind == theWindow) { ! 210: switch (but_event->button & 0xff) { ! 211: case Button1: ! 212: hx = but_event->x; ! 213: break; ! 214: case Button2: ! 215: if (but_event->state & ShiftMask) ! 216: exit(0); ! 217: if (width*2 < MAXWIDTH) ! 218: rescale(width*2); ! 219: break; ! 220: case Button3: ! 221: rescale(width/2); ! 222: } ! 223: drawhairl(); ! 224: drawnums(); ! 225: break; ! 226: } ! 227: break; ! 228: } ! 229: case MotionNotify: { ! 230: XPointerMovedEvent *mov_event = (XPointerMovedEvent *) &event; ! 231: int x, y, newx, dummy, mask; ! 232: Window mwid; ! 233: ! 234: wind = mwid; ! 235: XQueryPointer(dpy, theWindow, &mwid, &mwid, &x, &y, &dummy, &dummy, ! 236: &mask); ! 237: while (XPending(dpy) && (XPeekEvent(dpy, &event), ! 238: (event.type == MotionNotify))) ! 239: XNextEvent(dpy, &event); ! 240: if (wind == slidewid) { ! 241: if (mask & Button1Mask) ! 242: newx = x - START; ! 243: else if (mask & Button2Mask) ! 244: newx = x + END - width; ! 245: else ! 246: newx = x - xm; ! 247: if (newx != xo) { ! 248: xo = newx; ! 249: XMoveWindow(dpy, slidewid, xo, SLIDETOP); ! 250: drawnums(); ! 251: } ! 252: } else if (wind == theWindow) { ! 253: if (mask & Button1Mask) { ! 254: newx = x; ! 255: if (newx != hx) { ! 256: hx = newx; ! 257: drawhairl(); ! 258: drawnums(); ! 259: } ! 260: } ! 261: } ! 262: break; ! 263: } ! 264: case ButtonRelease: ! 265: break; ! 266: case EnterNotify: ! 267: case LeaveNotify: { ! 268: XCrossingEvent *cross_event = (XCrossingEvent *) &event; ! 269: ! 270: if (event.type == EnterNotify) ! 271: XSetWindowBorder(dpy,theWindow,ForeColor); ! 272: else if ((cross_event->window == theWindow) && ! 273: (cross_event->detail != NotifyInferior)) { ! 274: XSetWindowBorderPixmap(dpy,theWindow,dimBorder); ! 275: } ! 276: break; ! 277: } ! 278: case NoExpose: ! 279: break; ! 280: default: ! 281: printf("event type=%ld\n",event.type); ! 282: /* XSRError("Unexpected X_Event"); */ ! 283: ! 284: } /* end of switch */ ! 285: } /* end main loop */ ! 286: } ! 287: ! 288: ! 289: /***********************************/ ! 290: XSRError (identifier) ! 291: char *identifier; ! 292: { ! 293: fprintf(stderr, "xsr: %s\n", identifier); ! 294: exit(1); ! 295: } ! 296: ! 297: ! 298: rescale(w) ! 299: int w; ! 300: { ! 301: int x,y,wx,wy; ! 302: Window win; ! 303: int oldwidth, dummy; ! 304: ! 305: XGetGeometry(dpy, theWindow, &win, &wx, &wy, &oldwidth, &dummy, ! 306: &dummy, &dummy); ! 307: if (oldwidth != w) { ! 308: XQueryPointer(dpy, theWindow, &win, &win, &dummy, &dummy, &x, &y, ! 309: &dummy); ! 310: XMoveResizeWindow(dpy, theWindow, wx + x - (x * w)/oldwidth, wy, ! 311: w, HEIGHT); ! 312: } ! 313: hx = (hx * w) / width; ! 314: xo = (xo * w) / width; ! 315: width = w; ! 316: scalelen = width - START - END; ! 317: XResizeWindow(dpy, slidewid, width, SLIDEHIGH); ! 318: XResizeWindow(dpy, blackwid, width, SLIDEHIGH+2); ! 319: if (framePix) ! 320: XFreePixmap(dpy, framePix); ! 321: framePix = NULL; ! 322: drawframe(); ! 323: if (slidePix) ! 324: XFreePixmap(dpy, slidePix); ! 325: slidePix = NULL; ! 326: drawslide(); ! 327: XMoveWindow(dpy, slidewid, xo, SLIDETOP); ! 328: drawnums(); ! 329: drawhairl(); ! 330: } ! 331: ! 332: drawmark(win, x, y, height, topp) ! 333: Window win; ! 334: int x,y,height,topp; ! 335: { ! 336: XDrawLine(dpy, win, sgc, x, (topp?y:y+MAJORH-height), ! 337: x, height + (topp?y:y+MAJORH-height), ForeColor); ! 338: } ! 339: ! 340: dolabel(win, x, y, str, topp, majorp) ! 341: Window win; ! 342: int x,y; ! 343: char *str; ! 344: int topp,majorp; ! 345: { ! 346: XDrawString(dpy, win, sgc, x + 2, ! 347: (topp?y+FOFFSET+foffset:y+MAJORH-fheight+foffset), ! 348: str, strlen(str)); ! 349: } ! 350: ! 351: ! 352: drawframe() ! 353: { ! 354: int i,x,j,xx; ! 355: char str[5]; ! 356: int midpt = scalelen/2; ! 357: ! 358: if (framePix == NULL) ! 359: framePix = XCreatePixmap(dpy, theWindow, width, HEIGHT, 1); ! 360: XFillRectangle(dpy, framePix, cgc, 0, 0, width, HEIGHT); ! 361: XDrawString(dpy, framePix, sgc, LABEL, LSCALEH+foffset, "L", 1); ! 362: for (i = 0; i <= 10; i++) { ! 363: sprintf(str, "%d", i); ! 364: x = START+(i*scalelen)/10; ! 365: dolabel(framePix, x, LSCALEH, str, 0, 1); ! 366: drawmark(framePix, x, LSCALEH, MAJORH, 0); ! 367: for (j = 1; j < 10; j++) ! 368: drawmark(framePix, x+(j*scalelen)/100, LSCALEH, (j==5?MIDDH:MINORH), ! 369: 0); ! 370: } ! 371: XDrawString(dpy, framePix, sgc, LABEL, ASCALEH+foffset, "A", 1); ! 372: doscale(framePix, ASCALEH, START, midpt, 0); ! 373: doscale(framePix, ASCALEH, START + midpt, scalelen - midpt, 0); ! 374: XDrawString(dpy, framePix, sgc, LABEL, DSCALEH+foffset, "D", 1); ! 375: doscale(framePix, DSCALEH, START, scalelen, 1); ! 376: XDrawString(dpy, framePix, sgc, LABEL, DISCALEH+foffset, "DI", 2); ! 377: for (i = 1; i <= 10; i++) { ! 378: x = START + scalelen * (1 - log10((float) i)) + 0.5; ! 379: sprintf(str, "%d", (i==10?1:i)); ! 380: dolabel(framePix, x, DISCALEH, str, 1, 1); ! 381: drawmark(framePix, x, DISCALEH, MAJORH, 1); ! 382: } ! 383: XCopyArea(dpy, framePix, theWindow, sgc, 0, 0, scalelen + START+END, HEIGHT, 0, 0); ! 384: } ! 385: ! 386: doscale(win, high, offset, len, topp) ! 387: Window win; ! 388: int high, offset, len, topp; ! 389: { ! 390: int i,x,xx,j; ! 391: int xs[11]; ! 392: char str[6]; ! 393: ! 394: xs[0] = offset - 100; ! 395: for (i = 1; i <= 10; i++) ! 396: xs[i] = offset + len * log10((float) i) + 0.5; ! 397: ! 398: for (i = 1; i < 10; i++) { ! 399: if (xs[i] > xs[i-1] + LABELSPACE) { ! 400: sprintf(str, "%d", (i==10?1:i)); ! 401: dolabel(win, xs[i], high, str, topp, 1); ! 402: drawmark(win, xs[i], high, MAJORH, topp); ! 403: } else ! 404: drawmark(win, xs[i], high, MIDDH, topp); ! 405: ! 406: sprintf(str, "%d.", i); ! 407: dotenths(win, high, xs[i], xs[i+1]-xs[i], str, topp); ! 408: } ! 409: dolabel(win, xs[i], high, "1", topp, 1); ! 410: drawmark(win, xs[i], high, MAJORH, topp); ! 411: } ! 412: ! 413: ! 414: dotenths(win, high, offset, len, str, topp) ! 415: Window win; ! 416: int high, offset, len; ! 417: char *str; ! 418: int topp; ! 419: { ! 420: int i,x; ! 421: int xs[11]; ! 422: char nstr[8]; ! 423: ! 424: for (i = 0; i <= 10; i++ ) ! 425: xs[i] = offset + ! 426: len * log10((float) 1.0 + ((float) i) / 10.0) / log2; ! 427: ! 428: if (len < HALVES) ! 429: return; ! 430: if (len < FIFTHS) { ! 431: drawmark(win, xs[5], high, MINORH, topp); ! 432: return; ! 433: } ! 434: if (len < TENTHS) { ! 435: for (i = 0; i < 10; i += 2) ! 436: drawmark(win, xs[i], high, MINORH, topp); ! 437: return; ! 438: } ! 439: if (len < LABELFIFTH) { ! 440: for (i = 0; i < 10; i++) { ! 441: drawmark(win, xs[i], high, (x==5?MIDDH:MINORH), topp); ! 442: dotenths(win, high, xs[i], xs[i+1]-xs[i], "", topp); ! 443: } ! 444: return; ! 445: } ! 446: if (len < LABELTENTHS) { ! 447: for (i = 0; i < 10; i++) { ! 448: if (i == 5) { ! 449: sprintf(nstr, "%s%d", str, 5); ! 450: dolabel(win, xs[i], high, nstr, topp, 0); ! 451: } ! 452: drawmark(win, xs[i], high, (x==5?MAJORH:MIDDH), topp); ! 453: dotenths(win, high, xs[i], xs[i+1]-xs[i], "", topp); ! 454: } ! 455: } else { ! 456: for (i = 0; i < 10; i++) { ! 457: sprintf(nstr, "%s%d", str, i); ! 458: if (i > 0) { ! 459: dolabel(win, xs[i], high, nstr, topp, 0); ! 460: drawmark(win, xs[i], high, MAJORH, topp); ! 461: } ! 462: dotenths(win, high, xs[i], xs[i+1]-xs[i], nstr, topp); ! 463: } ! 464: } ! 465: } ! 466: ! 467: ! 468: ! 469: ! 470: drawslide() ! 471: { ! 472: int i,x,j; ! 473: char str[5]; ! 474: int midpt = scalelen/2; ! 475: ! 476: if (slidePix == NULL) ! 477: slidePix = XCreatePixmap(dpy, theWindow, width, SLIDEHIGH, 1); ! 478: XFillRectangle(dpy, slidePix, cgc, 0, 0, width, SLIDEHIGH); ! 479: XDrawString(dpy, slidePix, sgc, LABEL, BSCALEH+foffset, "B", 1); ! 480: doscale(slidePix, BSCALEH, START, midpt, 1); ! 481: doscale(slidePix, BSCALEH, START + midpt, scalelen - midpt, 1); ! 482: XDrawString(dpy, slidePix, sgc, LABEL, CISCALEH+foffset, "CI", 2); ! 483: for (i = 1; i <= 10; i++) { ! 484: x = START + scalelen * (1 - log10((float) i)) + 0.5; ! 485: sprintf(str, "%d", (i==10?1:i)); ! 486: dolabel(slidePix, x, CISCALEH, str, 1, 1); ! 487: drawmark(slidePix, x, CISCALEH, MAJORH, 1); ! 488: } ! 489: XDrawString(dpy, slidePix, sgc, LABEL, CSCALEH+foffset, "C", 1); ! 490: doscale(slidePix, CSCALEH, START, scalelen, 0); ! 491: XCopyArea(dpy, slidePix, slidewid, sgc, 0, 0, scalelen+START+END, SLIDEHIGH, 0, 0); ! 492: } ! 493: ! 494: redrawslide(x, y, w, h) ! 495: int x,y,w,h; ! 496: { ! 497: int i; ! 498: ! 499: if (slidePix != NULL) ! 500: XCopyArea(dpy, slidePix, slidewid, sgc, 0, 0, scalelen + START + END, SLIDEHIGH, ! 501: 0, 0); ! 502: else ! 503: drawslide(); ! 504: } ! 505: ! 506: redrawframe(x, y, w, h) ! 507: int x,y,w,h; ! 508: { ! 509: if (framePix != NULL) ! 510: XCopyArea(dpy, framePix, theWindow, sgc, 0, 0, scalelen + START + END, HEIGHT, ! 511: 0, 0); ! 512: else ! 513: drawframe(); ! 514: } ! 515: ! 516: drawhairl() ! 517: { ! 518: XMoveWindow(dpy, hairlwid, hx, 0); ! 519: XClearWindow(dpy, hairlwid); ! 520: } ! 521: ! 522: drawnums() ! 523: { ! 524: char str[10]; ! 525: float x = ((float) (hx - START))/((float) scalelen); ! 526: float xs = ((float) (hx - START - xo))/((float) scalelen); ! 527: ! 528: XClearWindow(dpy, dispwid); ! 529: sprintf(str, "%5f", 10. * x); ! 530: XDrawImageString(dpy, dispwid, sgc, 5, LSCALEH+foffset, str, strlen(str)); ! 531: sprintf(str, "%5f", pow(100., x)); ! 532: XDrawImageString(dpy, dispwid, sgc, 5, ASCALEH+foffset, str, strlen(str)); ! 533: sprintf(str, "%5f", pow(100., xs)); ! 534: XDrawImageString(dpy, dispwid, sgc, 5, SLIDETOP+foffset + BSCALEH, str, strlen(str)); ! 535: sprintf(str, "%5f", pow(10., 1. - xs)); ! 536: XDrawImageString(dpy, dispwid, sgc, 5, SLIDETOP+foffset + CISCALEH, str, strlen(str)); ! 537: sprintf(str, "%5f", pow(10., xs)); ! 538: XDrawImageString(dpy, dispwid, sgc, 5, SLIDETOP+foffset + CSCALEH, str, strlen(str)); ! 539: sprintf(str, "%5f", pow(10., x)); ! 540: XDrawImageString(dpy, dispwid, sgc, 5, DSCALEH+foffset, str, strlen(str)); ! 541: sprintf(str, "%5f", pow(10., 1. - x)); ! 542: XDrawImageString(dpy, dispwid, sgc, 5, DISCALEH+foffset, str, strlen(str)); ! 543: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.