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