|
|
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.