Annotation of researchv9/X11/src/X.V11R1/clients/xcalc/xcalc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     $Source: /u1/X11/clients/xcalc/RCS/xcalc.c,v $
        !             3:  *     $Header: xcalc.c,v 1.4 87/09/12 19:00:36 rws Exp $
        !             4:  */
        !             5: 
        !             6: #ifndef lint
        !             7: static char *rcsid_xcalc_c = "$Header: xcalc.c,v 1.4 87/09/12 19:00:36 rws Exp $";
        !             8: #endif lint
        !             9: 
        !            10: /*
        !            11:  * xcalc.c  -  a hand calculator for the X Window system
        !            12:  *
        !            13:  *  Author:    John H. Bradley, University of Pennsylvania
        !            14:  *                ([email protected])
        !            15:  *                     March, 1987
        !            16:  *
        !            17:  *  RPN mode added and port to X11 by Mark Rosenstein, MIT Project Athena
        !            18:  */
        !            19: 
        !            20: /*
        !            21:  * color usage:  ForeColor is used for all frames, BackColor is the color of 
        !            22:  *                  the calculator body.
        !            23:  *               NKeyFore, NKeyBack are the colors used for the number keys.
        !            24:  *               OKeyFore, OKeyBack are used for the operator keys (+-*=/).
        !            25:  *               FKeyFore, FKeyBack are used for all the other keys.
        !            26:  *               DispFore, DispBack are used for the display.
        !            27:  *               IconFore, IconBack are used for the display.
        !            28:  *
        !            29:  *               if running on monochrome monitor, or if 'stipple' option
        !            30:  *                  set, the calculator body is a 50% stipple of ForeColor
        !            31:  *                  and BackColor.  This looks nice in mono, but can prevent
        !            32:  *                  you from getting the 'right' colors in color mode, so
        !            33:  *                  it's an option.
        !            34:  */
        !            35: 
        !            36: #include <stdio.h>
        !            37: #include <math.h>
        !            38: #include <strings.h>
        !            39: #include <signal.h>
        !            40: #include <X11/Xlib.h>
        !            41: #include <X11/Xutil.h>
        !            42: #include <X11/cursorfont.h>
        !            43: #include <sys/time.h>
        !            44: #include <setjmp.h>
        !            45: 
        !            46: /* program icon */
        !            47: #include "icon"
        !            48: 
        !            49: extern int errno;
        !            50: 
        !            51: 
        !            52: /* constants used for setting up the calculator.  changing them would 
        !            53:    probably be bad.  If you do, don't forget to change the values in the
        !            54:    syntax routine */
        !            55: 
        !            56: #define KFONT "helvetica-medium9"
        !            57: #define DFONT "helvetica-bold12"
        !            58: #define FFONT "helvetica-medium8"
        !            59: #define PADDINGW    4
        !            60: #define PADDINGH    8
        !            61: #define DEF_BDRWIDE 2
        !            62: #define MAXDISP     11
        !            63: #define KEYPADH     3
        !            64: #define KEYPADW     2
        !            65: #define EXTRAH      2
        !            66: #define DISPPADH    4
        !            67: #define DISPPADW    8
        !            68: #define FLAGH       10
        !            69: #define PI          3.14159265358979
        !            70: #define E           2.71828182845904
        !            71: 
        !            72: /* DRG mode.  used for trig calculations */
        !            73: #define DEG 0
        !            74: #define RAD 1
        !            75: #define GRAD 2
        !            76: 
        !            77: 
        !            78: /* fonts */
        !            79: char *kfont, *dfont, *ffont;
        !            80: 
        !            81: /* colors */
        !            82: int ForeColor, BackColor, NKeyFore, NKeyBack, OKeyFore, OKeyBack;
        !            83: int FKeyFore, FKeyBack, DispFore, DispBack, IconFore, IconBack;
        !            84: 
        !            85: int border = DEF_BDRWIDE;
        !            86: 
        !            87: 
        !            88: /* objects */
        !            89: Display         *dpy;
        !            90: Window   theWindow, iconWindow, dispwid;
        !            91: Cursor   arrow;
        !            92: Font     keyfont, dispfont, flagfont;
        !            93: XFontStruct *kfontinfo, *dfontinfo, *ffontinfo; 
        !            94: Pixmap   stipplePix, dimBorder, IconPix;
        !            95: GC      dispbgc,dispfgc,keygc,keyigc,flaggc;
        !            96: 
        !            97: /* variables used in setup */
        !            98: int numkeys, dispwide, disphigh, keywide, keyhigh;
        !            99: 
        !           100: 
        !           101: /* RPN or Infix mode */
        !           102: int rpn          = 0;      /* infix syntax as default */
        !           103: 
        !           104: /* display flags */
        !           105: int flagK, flagINV, flagPAREN, flagM, flagE, drgmode;
        !           106: char dispstr[32];
        !           107: 
        !           108: 
        !           109: /* stuff defining the keyboard layout.  The keypad is a 5x8 matrix of keys */
        !           110: #define TINUMKEYS 40
        !           111: #define HPNUMKEYS 39
        !           112: 
        !           113: struct _key {
        !           114:            char   *st;
        !           115:           int    code;
        !           116:           int    (*fun)();
        !           117:            Window wid;
        !           118:            short  x,y,width,height;
        !           119:            int    fore,back;
        !           120:           void   (*func)();
        !           121:             };
        !           122: 
        !           123: struct _key *key;
        !           124:              
        !           125: #define kRECIP 0
        !           126: #define kSQR   1
        !           127: #define kSQRT  2
        !           128: #define kCLR   3
        !           129: #define kOFF   4
        !           130: #define kINV   5
        !           131: #define kSIN   6
        !           132: #define kCOS   7
        !           133: #define kTAN   8
        !           134: #define kDRG   9
        !           135: #define kE     10
        !           136: #define kEE    11
        !           137: #define kLOG   12
        !           138: #define kLN    13
        !           139: #define kPOW   14
        !           140: #define kPI    15
        !           141: #define kFACT  16
        !           142: #define kLPAR  17
        !           143: #define kRPAR  18
        !           144: #define kDIV   19
        !           145: #define kSTO   20
        !           146: #define kSEVEN 21
        !           147: #define kEIGHT 22
        !           148: #define kNINE  23
        !           149: #define kMUL   24
        !           150: #define kRCL   25
        !           151: #define kFOUR  26
        !           152: #define kFIVE  27
        !           153: #define kSIX   28
        !           154: #define kSUB   29
        !           155: #define kSUM   30
        !           156: #define kONE   31
        !           157: #define kTWO   32
        !           158: #define kTHREE 33
        !           159: #define kADD   34
        !           160: #define kEXC   35
        !           161: #define kZERO  36
        !           162: #define kDEC   37
        !           163: #define kNEG   38
        !           164: #define kEQU   39
        !           165: #define kENTR  40
        !           166: #define kXXY   41
        !           167: #define kEXP   42
        !           168: #define k10X   43
        !           169: #define kROLL  44
        !           170: #define kNOP   45
        !           171: #define kBKSP  46
        !           172: 
        !           173: 
        !           174: int  oneop(),twoop(),clearf(),offf(),invf(),drgf(),eef();
        !           175: int  lparf(),rparf(),digit(),decf(),negf(),equf();
        !           176: 
        !           177: /* "1/x", "x^2", "SQRT","CE/C", "AC",
        !           178:    "INV", "sin", "cos", "tan",  "DRG",
        !           179:    "e",   "EE",  "log", "ln",   "y^x",
        !           180:    "PI",  "x!",  "(",   ")",    "/",
        !           181:    "STO", "7",   "8",   "9",    "*",
        !           182:    "RCL", "4",   "5",   "6",    "-",
        !           183:    "SUM", "1",   "2",   "3",    "+",
        !           184:    "EXC", "0",   ".",   "+/-",  "="  */
        !           185: 
        !           186: struct _key tikeys[TINUMKEYS] = {
        !           187:   {"1/x",kRECIP,oneop}, {"x^2",kSQR,oneop}, {"SQRT",kSQRT,oneop},
        !           188:   {"CE/C",kCLR,clearf}, {"AC",kOFF,offf},
        !           189:   {"INV",kINV,invf}, {"sin",kSIN,oneop}, {"cos",kCOS,oneop},
        !           190:   {"tan",kTAN,oneop}, {"DRG",kDRG,drgf},
        !           191:   {"e",kE,oneop}, {"EE",kEE,eef}, {"log",kLOG,oneop},
        !           192:   {"ln",kLN,oneop},{"y^x",kPOW,twoop},
        !           193:   {"PI",kPI,oneop},{"x!",kFACT,oneop},{"(",kLPAR,lparf},
        !           194:   {")",kRPAR,rparf},{"/",kDIV,twoop},
        !           195:   {"STO",kSTO,oneop},{"7",kSEVEN,digit},{"8",kEIGHT,digit},
        !           196:   {"9",kNINE,digit},{"*",kMUL,twoop},
        !           197:   {"RCL",kRCL,oneop},{"4",kFOUR,digit},{"5",kFIVE,digit},
        !           198:   {"6",kSIX,digit},{"-",kSUB,twoop},
        !           199:   {"SUM",kSUM,oneop},{"1",kONE,digit},{"2",kTWO,digit},
        !           200:   {"3",kTHREE,digit},{"+",kADD,twoop},
        !           201:   {"EXC",kEXC,oneop},{"0",kZERO,digit},{".",kDEC,decf},
        !           202:   {"+/-",kNEG,negf},{"=",kEQU,equf}};
        !           203: 
        !           204: int  twof(),nop(),rollf(),bkspf(),entrf(),memf();
        !           205: 
        !           206: /*  { "SQRT","e^x", "10^x", "y^x", "1/x", "CHS", "7", "8", "9",  "/",
        !           207:       "x!",  "PI",  "sin",  "cos", "tan", "EEX", "4", "5", "6",  "x",
        !           208:       "",    "",    "R v",  "x:y", "<-",  "ENTR","1", "2", "3",  "-",
        !           209:       "ON",  "DRG", "INV",  "STO", "RCL",        "0", ".", "SUM","+"  */
        !           210: 
        !           211: struct _key hpkeys[HPNUMKEYS] = {
        !           212:   {"SQRT",kSQRT,oneop},{"e^x",kEXP,oneop},{"10^x",k10X,oneop},
        !           213:   {"y^x",kPOW,twof},{"1/x",kRECIP,oneop},{"CHS",kNEG,negf},
        !           214:   {"7",kSEVEN,digit},{"8",kEIGHT,digit},{"9",kNINE,digit},{"/",kDIV,twof},
        !           215: 
        !           216:   {"x!",kFACT,oneop},{"PI",kPI,oneop},{"sin",kSIN,oneop},{"cos",kCOS,oneop},
        !           217:   {"tan",kTAN,oneop},{"EEX",kEE,eef},{"4",kFOUR,digit},{"5",kFIVE,digit},
        !           218:   {"6",kSIX,digit},{"x",kMUL,twof},
        !           219: 
        !           220:   {"",kNOP,nop},{"",kNOP,nop},{"R v",kROLL,rollf},{"x:y",kXXY,twof},
        !           221:   {"<-",kBKSP,bkspf},{"ENTR",kENTR,entrf},{"1",kONE,digit},{"2",kTWO,digit},
        !           222:   {"3",kTHREE,digit},{"-",kSUB,twof},
        !           223: 
        !           224:   {"ON",kOFF,offf},{"DRG",kDRG,drgf},{"INV",kINV,invf},{"STO",kSTO,memf},
        !           225:   {"RCL",kRCL,memf},{"0",kZERO,digit},{".",kDEC,decf},
        !           226:   {"SUM",kSUM,memf},{"+",kADD,twof} };
        !           227: 
        !           228: 
        !           229: /* checkerboard used in mono mode */
        !           230: #define check_width 16
        !           231: #define check_height 16
        !           232: static char check_bits[] = {
        !           233:    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
        !           234:    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
        !           235:    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa};
        !           236: 
        !           237: 
        !           238: #ifndef IEEE
        !           239:     jmp_buf env;
        !           240: #endif
        !           241: 
        !           242: 
        !           243: /**************/
        !           244: main(argc, argv)
        !           245:     int   argc;
        !           246:     char *argv[];
        !           247: /**************/
        !           248: {
        !           249:     int i, status,dpcs;
        !           250:     char *strind;
        !           251: #ifndef IEEE
        !           252:     extern fperr();
        !           253: #endif
        !           254: 
        !           255:     char *fc, *bc, *nfc, *nbc, *ofc, *obc, *ffc, *fbc, *dfc, *dbc, *ifc, *ibc;
        !           256:     char *geom    = NULL;
        !           257:     char *display = NULL;
        !           258:     int rvflag    = 0;      /* don't use reverse video as a default */
        !           259:     int stip      = 0;      /* don't stipple background by default */
        !           260:     int analog   = 0;
        !           261:     int invkey    = -1;
        !           262: 
        !           263:     XEvent     event;
        !           264:     XGCValues  gcv;
        !           265:     XWMHints   wmhints;
        !           266:     Colormap   colors;
        !           267:     XColor     xcsd, xced;
        !           268:     int min_width, min_height;
        !           269:     XSizeHints szhint;
        !           270: 
        !           271:     char *def;
        !           272: 
        !           273: 
        !           274: 
        !           275:     /*********************Defaults*********************/
        !           276:     kfont=XGetDefault(dpy,argv[0],"KeyFont");
        !           277:     if (!kfont) kfont = KFONT;    
        !           278: 
        !           279:     dfont=XGetDefault(dpy,argv[0],"DisplayFont");
        !           280:     if (!dfont) dfont = DFONT;    
        !           281: 
        !           282:     ffont=XGetDefault(dpy,argv[0],"FlagFont");
        !           283:     if (!ffont) ffont = FFONT;    
        !           284: 
        !           285:     if ((def=XGetDefault(dpy,argv[0],"BorderWidth"))!=NULL)
        !           286:          border=atoi(def);
        !           287: 
        !           288:     if ((def=XGetDefault(dpy,argv[0],"ReverseVideo"))!=NULL)
        !           289:          if (strcmp(def,"on")==0) rvflag=1;
        !           290: 
        !           291:     if ((def=XGetDefault(dpy,argv[0],"Stipple"))!=NULL)
        !           292:          if (strcmp(def,"on")==0) stip=1;
        !           293: 
        !           294:     if ((def=XGetDefault(dpy,argv[0],"Mode"))!=NULL) {
        !           295:          if (strcmp(def,"rpn")==0) rpn=1;
        !           296:          else if (strcmp(def,"analog")==0) analog=1;
        !           297:          }
        !           298: 
        !           299:     fc  = XGetDefault(dpy, argv[0], "Foreground");
        !           300:     bc  = XGetDefault(dpy, argv[0], "Background");
        !           301:     nfc = XGetDefault(dpy, argv[0], "NKeyFore");
        !           302:     nbc = XGetDefault(dpy, argv[0], "NKeyBack");
        !           303:     ofc = XGetDefault(dpy, argv[0], "OKeyFore");
        !           304:     obc = XGetDefault(dpy, argv[0], "OKeyBack");
        !           305:     ffc = XGetDefault(dpy, argv[0], "FKeyFore");
        !           306:     fbc = XGetDefault(dpy, argv[0], "FKeyBack");
        !           307:     dfc = XGetDefault(dpy, argv[0], "DispFore");
        !           308:     dbc = XGetDefault(dpy, argv[0], "DispBack");
        !           309:     ifc = XGetDefault(dpy, argv[0], "IconFore");
        !           310:     ibc = XGetDefault(dpy, argv[0], "IconBack");
        !           311: 
        !           312:     /*********************Options*********************/
        !           313: 
        !           314:     for (i = 1; i < argc; i++) {
        !           315: 
        !           316:         if (argv[i][0] == '=') {
        !           317:             geom = argv[i];
        !           318:             continue;
        !           319:             }
        !           320: 
        !           321:         strind = index(argv[i], ':');
        !           322: 
        !           323:         if(strind != NULL) {
        !           324:             display = argv[i];
        !           325:             continue;
        !           326:             }
        !           327: 
        !           328:         if (strcmp(argv [i], "-bw") == 0) {
        !           329:             if (++i >= argc) Syntax(argv[0]);
        !           330:             border = atoi(argv [i]);
        !           331:             continue;
        !           332:             }
        !           333: 
        !           334:         if (strcmp(argv [i], "-stip") == 0) {
        !           335:             stip=1;
        !           336:             continue;
        !           337:             }
        !           338: 
        !           339:         if (strcmp(argv [i], "-help") == 0) {
        !           340:             Syntax(argv[0]);
        !           341:             }
        !           342: 
        !           343:         if (strcmp(argv [i], "-rv") == 0) {
        !           344:             rvflag++;
        !           345:             continue;
        !           346:             }
        !           347: 
        !           348:         if (strcmp(argv [i], "-rpn") == 0) {
        !           349:             rpn++;
        !           350:             continue;
        !           351:             }
        !           352: 
        !           353:         if (strcmp(argv [i], "-analog") == 0) {
        !           354:             analog++;
        !           355:             continue;
        !           356:             }
        !           357: 
        !           358:         Syntax(argv[0]);
        !           359:     }
        !           360: 
        !           361: 
        !           362:     /*****************************************************/
        !           363: 
        !           364:     /* Open up the display. */
        !           365: 
        !           366:     if ((dpy = XOpenDisplay(display)) == NULL) {
        !           367:         fprintf(stderr, "%s: Can't open display '%s'\n",argv[0], display);
        !           368:         exit(1);
        !           369:         }
        !           370: 
        !           371:     /* Set up colors and pixmaps. */
        !           372: 
        !           373:     /* Set normal default colors */
        !           374:     if (!rvflag) {
        !           375:       ForeColor=BlackPixel(dpy, DefaultScreen(dpy));
        !           376:       BackColor=WhitePixel(dpy, DefaultScreen(dpy));
        !           377:     } else {
        !           378:       BackColor=BlackPixel(dpy, DefaultScreen(dpy));
        !           379:       ForeColor=WhitePixel(dpy, DefaultScreen(dpy));
        !           380:     }
        !           381: 
        !           382:     dpcs=DisplayCells(dpy, DefaultScreen(dpy));
        !           383:     if (dpcs<=2) stip=1;  /* monochrome display */
        !           384: 
        !           385:     colors = DefaultColormap(dpy, DefaultScreen(dpy));
        !           386: 
        !           387:     if (dpcs>2&&(fc !=NULL)&&XAllocNamedColor(dpy, colors, fc, &xcsd, &xced))
        !           388:       ForeColor=xcsd.pixel;
        !           389: 
        !           390:     if (dpcs>2&&(bc !=NULL)&&XAllocNamedColor(dpy, colors, bc, &xcsd, &xced))
        !           391:       BackColor=xcsd.pixel;
        !           392: 
        !           393:     NKeyFore = OKeyFore = FKeyFore = DispFore = IconFore = ForeColor;
        !           394:     NKeyBack = OKeyBack = FKeyBack = DispBack = IconBack = BackColor;
        !           395: 
        !           396:     if (dpcs>2&&(nfc !=NULL)&&XAllocNamedColor(dpy, colors, nfc, &xcsd, &xced))
        !           397:       NKeyFore=xcsd.pixel;
        !           398: 
        !           399:     if (dpcs>2&&(nbc !=NULL)&&XAllocNamedColor(dpy, colors, nbc, &xcsd, &xced))
        !           400:       NKeyBack=xcsd.pixel;
        !           401: 
        !           402:     if (dpcs>2&&(ofc !=NULL)&&XAllocNamedColor(dpy, colors, ofc, &xcsd, &xced))
        !           403:       OKeyFore=xcsd.pixel;
        !           404: 
        !           405:     if (dpcs>2&&(obc !=NULL)&&XAllocNamedColor(dpy, colors, obc, &xcsd, &xced))
        !           406:       OKeyBack=xcsd.pixel;
        !           407: 
        !           408:     if (dpcs>2&&(ffc !=NULL)&&XAllocNamedColor(dpy, colors, ffc, &xcsd, &xced))
        !           409:       FKeyFore=xcsd.pixel;
        !           410: 
        !           411:     if (dpcs>2&&(fbc !=NULL)&&XAllocNamedColor(dpy, colors, fbc, &xcsd, &xced))
        !           412:       FKeyBack=xcsd.pixel;
        !           413: 
        !           414:     if (dpcs>2&&(dfc !=NULL)&&XAllocNamedColor(dpy, colors, dfc, &xcsd, &xced))
        !           415:       DispFore=xcsd.pixel;
        !           416: 
        !           417:     if (dpcs>2&&(dbc !=NULL)&&XAllocNamedColor(dpy, colors, dbc, &xcsd, &xced))
        !           418:       DispBack=xcsd.pixel;
        !           419: 
        !           420:     if (dpcs>2&&(ifc !=NULL)&&XAllocNamedColor(dpy, colors, ifc, &xcsd, &xced))
        !           421:       IconFore=xcsd.pixel;
        !           422: 
        !           423:     if (dpcs>2&&(ibc !=NULL)&&XAllocNamedColor(dpy, colors, ibc, &xcsd, &xced))
        !           424:       IconBack=xcsd.pixel;
        !           425: 
        !           426:     /* load fonts, figure out sizes of keypad and display */
        !           427:     kfontinfo = XLoadQueryFont(dpy, kfont);
        !           428:     if (!kfontinfo) kfontinfo = XLoadQueryFont(dpy, "fixed");
        !           429:     if (!kfontinfo) XCalcError("Can't open '%s' or 'fixed' font\n",KFONT);
        !           430:     keyfont = kfontinfo->fid;
        !           431: 
        !           432:     dfontinfo = XLoadQueryFont(dpy, dfont);
        !           433:     if (!dfontinfo) dfontinfo = XLoadQueryFont(dpy, "fixed");
        !           434:     if (!dfontinfo) XCalcError("Can't open '%s' or 'fixed' font\n",DFONT);
        !           435:     dispfont = dfontinfo->fid;
        !           436: 
        !           437:     ffontinfo = XLoadQueryFont(dpy, ffont);
        !           438:     if (!ffontinfo) ffontinfo = XLoadQueryFont(dpy, "fixed");
        !           439:     if (!ffontinfo) XCalcError("Can't open '%s' or 'fixed' font\n",FFONT);
        !           440:     flagfont = ffontinfo->fid;
        !           441: 
        !           442:     keywide = XTextWidth(kfontinfo, "MMM", 3) + KEYPADW;
        !           443:     keyhigh = kfontinfo->ascent + KEYPADH + (rpn ? 2*EXTRAH : 0);
        !           444: 
        !           445:     dispwide  = (rpn ? 6 : 5)*keywide+4*PADDINGW;
        !           446:     disphigh = dfontinfo->ascent + DISPPADH + FLAGH;
        !           447: 
        !           448:     /* Create Stipple pattern */
        !           449:     stipplePix = XCreateBitmapFromData (dpy, DefaultRootWindow(dpy),
        !           450:         check_bits, check_width, check_height);
        !           451:        
        !           452:     dimBorder        = stipplePix;
        !           453: 
        !           454:     /* Create Icon Pixmap */
        !           455:     IconPix = XCreateBitmapFromData (dpy, DefaultRootWindow(dpy),
        !           456:         icon_bits, icon_width, icon_height);
        !           457: 
        !           458:     if (analog)
        !           459:       do_sr(argc, argv, geom, border);
        !           460: 
        !           461:     /* Open the main window. */
        !           462: 
        !           463:     if (rpn) {
        !           464:        min_width  = 10*keywide + 11*PADDINGW + 2;
        !           465:        min_height = disphigh + 4*keyhigh + 6*PADDINGH + 2;
        !           466:     } else {
        !           467:        min_width  = dispwide + 2*PADDINGW + 2;
        !           468:        min_height = disphigh + 2 + 8*keyhigh + 10*PADDINGH + 10*EXTRAH;
        !           469:     }
        !           470: 
        !           471:     theWindow = XCreateSimpleWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
        !           472:                                    0, 0, min_width, min_height, border,
        !           473:                                    ForeColor, BackColor);
        !           474:     if (!theWindow) XCalcError("Can't open calculator window");
        !           475: 
        !           476:     if (stip)
        !           477:       XSetWindowBackgroundPixmap(dpy, theWindow, stipplePix);
        !           478: 
        !           479:     szhint.flags = PSize|PMinSize;
        !           480:     szhint.width = szhint.min_width = min_width;
        !           481:     szhint.height = szhint.min_height = min_height;
        !           482:     XSetStandardProperties(dpy, theWindow, "Calculator", NULL, IconPix,
        !           483:                           argv, argc, &szhint);
        !           484: 
        !           485:     gcv.function = GXcopyInverted;
        !           486:     gcv.foreground = DispFore;
        !           487:     gcv.background = DispBack;
        !           488:     gcv.font = dispfont;
        !           489:     dispbgc = XCreateGC(dpy, theWindow,
        !           490:                        GCForeground|GCBackground|GCFunction|GCFont, &gcv);
        !           491:     gcv.function = GXcopy;
        !           492:     dispfgc = XCreateGC(dpy, theWindow,
        !           493:                        GCForeground|GCBackground|GCFunction|GCFont, &gcv);
        !           494:     gcv.font = flagfont;
        !           495:     flaggc = XCreateGC(dpy, theWindow,
        !           496:                        GCForeground|GCBackground|GCFunction|GCFont, &gcv);
        !           497:     gcv.function = GXcopy;
        !           498:     gcv.foreground = NKeyFore;
        !           499:     gcv.background = NKeyBack;
        !           500:     gcv.font = keyfont;
        !           501:     keygc = XCreateGC(dpy, theWindow,
        !           502:                      GCForeground|GCBackground|GCFunction|GCFont, &gcv);
        !           503:     gcv.function = GXinvert;
        !           504:     keyigc = XCreateGC(dpy, theWindow, GCFunction, &gcv);
        !           505:                        
        !           506: 
        !           507:     if (rpn)
        !           508:       SetupHPCalc();
        !           509:     else
        !           510:       SetupTICalc();
        !           511: 
        !           512:     ResetCalc();
        !           513: 
        !           514:     XSelectInput(dpy, theWindow, ExposureMask|KeyPressMask|EnterWindowMask|
        !           515:                                 LeaveWindowMask);
        !           516:     XSelectInput(dpy, dispwid,   ExposureMask|EnterWindowMask|LeaveWindowMask);
        !           517: 
        !           518:     for (i=0; i<numkeys; i++)
        !           519:         XSelectInput(dpy,key[i].wid,ExposureMask|ButtonPressMask|
        !           520:                          ButtonReleaseMask|EnterWindowMask|LeaveWindowMask);
        !           521:     XMapWindow    (dpy, theWindow);
        !           522:     XMapSubwindows(dpy, theWindow);
        !           523:     arrow=XCreateFontCursor(dpy, XC_hand2);
        !           524:     XDefineCursor(dpy, theWindow,arrow);
        !           525: 
        !           526:     /*********** Set up SIGFPE hander ***********/
        !           527: #ifndef IEEE
        !           528:     signal(SIGFPE,fperr);
        !           529: #endif
        !           530: 
        !           531:     /**************** Main loop *****************/
        !           532: 
        !           533:     while (1) {
        !           534:         Window wind;
        !           535: 
        !           536:         XNextEvent(dpy, &event);
        !           537: 
        !           538:         switch (event.type) {
        !           539: 
        !           540:         case Expose: {
        !           541:             XExposeEvent *exp_event = (XExposeEvent *) &event;
        !           542:             wind = exp_event->window;
        !           543: 
        !           544:            if (wind==theWindow) XClearArea(dpy,theWindow,exp_event->x,
        !           545:                                            exp_event->y,exp_event->width,
        !           546:                                            exp_event->height,False);
        !           547:            else if (wind==dispwid) DrawDisplay();
        !           548:             else if (wind==iconWindow)
        !           549:              ;
        !           550:             else {
        !           551:                 for (i=0; i<numkeys; i++) {
        !           552:                    if (key[i].wid==wind) DrawKey(i);
        !           553:                    }
        !           554:                 }
        !           555:             }
        !           556:             break;
        !           557: 
        !           558:         case ButtonPress: {
        !           559:             XButtonPressedEvent *but_event = (XButtonPressedEvent *) &event;
        !           560:             wind = but_event->window;
        !           561:             if ((but_event->button & 0xff) == Button1) {
        !           562:                 for (i=0; i<numkeys; i++) {
        !           563:                    if (key[i].wid==wind) { InvertKey(i); invkey=i; }
        !           564:                    }
        !           565:                 }
        !           566: 
        !           567:             else if ((but_event->button & 0xff) == Button3) {
        !           568:              for (i=0; i<numkeys; i++) {
        !           569:                if (key[i].wid==wind && key[i].code==kOFF)
        !           570:                  Quit();
        !           571:              }
        !           572:            }
        !           573:            else XBell(dpy, 0);
        !           574:            }
        !           575:             break;
        !           576:                        
        !           577:         case ButtonRelease: {
        !           578:             XButtonReleasedEvent *but_event = (XButtonReleasedEvent *) &event;
        !           579:             wind = but_event->window;
        !           580:             if ((but_event->button & 0xff) == Button1) {
        !           581:                 for (i=0; i<numkeys; i++) {
        !           582:                    if (key[i].wid==wind) LetGoKey(invkey);
        !           583:                    }
        !           584:                 invkey = -1;
        !           585:                 }
        !           586:             }
        !           587:             break;
        !           588: 
        !           589:         case KeyPress: {
        !           590:             XKeyPressedEvent *key_event = (XKeyPressedEvent *) &event;
        !           591:            char *st, keybuf[10];
        !           592:             wind = key_event->window;
        !           593:             if (wind==theWindow) {
        !           594:              i = XLookupString(key_event, keybuf, sizeof(keybuf), NULL, NULL);
        !           595:              for (st = keybuf; i > 0; i--)
        !           596:                TypeChar(*st++);
        !           597:            } else 
        !           598:              printf("KeyPressed in window %ld\n",wind);
        !           599:            }
        !           600:            break;
        !           601: 
        !           602:        case EnterNotify:
        !           603:        case LeaveNotify: {
        !           604:            XCrossingEvent *cross_event = (XCrossingEvent *) &event;
        !           605: 
        !           606:            if ((cross_event->detail != NotifyInferior) &&
        !           607:                (cross_event->window == theWindow) &&
        !           608:                (cross_event->mode == NotifyNormal) &&
        !           609:                cross_event->focus) {
        !           610:                if (event.type == EnterNotify)
        !           611:                    XSetWindowBorder(dpy,theWindow,ForeColor);
        !           612:                else
        !           613:                    XSetWindowBorderPixmap(dpy,theWindow,dimBorder);
        !           614:            }
        !           615:             break;
        !           616:          }
        !           617:         default:
        !           618:            printf("event type=%ld\n",event.type); 
        !           619:            XCalcError("Unexpected X_Event");
        !           620: 
        !           621:         }  /* end of switch */
        !           622:     }  /* end main loop */}
        !           623: 
        !           624: 
        !           625: 
        !           626: /***********************************/
        !           627: Syntax(call)
        !           628:  char *call;
        !           629: {
        !           630:     printf ("Usage: %s [-bw <pixels>] [-stip] [-help] [-rv] [-rpn] [-analog]\n", call);
        !           631:     printf ("          [[<host>]:[<vs>]] [=geometry]\n\n");
        !           632:     printf ("Default: %s -bw %d =156x226-16-16\n\n",call, DEF_BDRWIDE);
        !           633:     exit(0);
        !           634: }
        !           635: 
        !           636: 
        !           637: /***********************************/
        !           638: XCalcError(identifier,arg1,arg2,arg3,arg4)
        !           639:        char *identifier,*arg1,*arg2,*arg3,*arg4;
        !           640: {
        !           641:     fprintf(stderr, identifier, arg1,arg2,arg3,arg4);
        !           642:     exit(1);
        !           643: }
        !           644: 
        !           645: 
        !           646: 
        !           647: /***********************************/
        !           648: SetupTICalc()
        !           649: {
        !           650:     int i;
        !           651: 
        !           652:     numkeys=TINUMKEYS;
        !           653:     key = &tikeys[0];
        !           654: 
        !           655:     for (i=0; i<numkeys; i++) {
        !           656:         key[i].x = PADDINGW+(i%5)*(keywide+PADDINGW);
        !           657:         key[i].y = disphigh+2+2*PADDINGH+(i/5)*(keyhigh+PADDINGH);
        !           658:         key[i].width = keywide;
        !           659:         key[i].height = keyhigh;
        !           660:         if (i>=15) {
        !           661:             key[i].height+=(2*EXTRAH);
        !           662:             key[i].y     += ((i-15)/5)*EXTRAH*2;
        !           663:             }
        !           664: 
        !           665:         switch (tikeys[i].code) {
        !           666:             case kZERO:  case kONE:  case kTWO:  case kTHREE:
        !           667:             case kFOUR:  case kFIVE: case kSIX:  case kSEVEN:
        !           668:             case kEIGHT: case kNINE: case kDEC:  case kNEG:
        !           669:                 key[i].fore=NKeyFore;
        !           670:                 key[i].back=NKeyBack;
        !           671:                 break;
        !           672:             case kADD:   case kSUB:  case kMUL:  case kDIV:  case kEQU:
        !           673:                 key[i].fore=OKeyFore;
        !           674:                 key[i].back=OKeyBack;
        !           675:                 break;
        !           676:             default:
        !           677:                 key[i].fore=FKeyFore;
        !           678:                 key[i].back=FKeyBack;
        !           679:             }
        !           680:        key[i].wid=XCreateSimpleWindow(dpy,theWindow,key[i].x,key[i].y,
        !           681:                                       key[i].width,key[i].height,1,
        !           682:                                       key[i].fore,key[i].back);
        !           683:         }
        !           684: 
        !           685:     dispwid = XCreateSimpleWindow(dpy,theWindow,PADDINGW,PADDINGH,
        !           686:                                  dispwide-2,disphigh,2,DispFore,DispBack);
        !           687: }
        !           688: 
        !           689: SetupHPCalc()
        !           690: {
        !           691:     int i,j;
        !           692: 
        !           693:     numkeys=HPNUMKEYS;
        !           694:     key = &hpkeys[0];
        !           695: 
        !           696:     for (i=0; i<numkeys; i++) {
        !           697:         j = (i<35)? i : i + 1;
        !           698:         key[i].x = PADDINGW+(j%10)*(keywide+PADDINGW);
        !           699:         key[i].y = disphigh+2+2*PADDINGH+(j/10)*(keyhigh+PADDINGH);
        !           700:         key[i].width = keywide;
        !           701:         key[i].height = keyhigh;
        !           702:         if (i==25) {
        !           703:             key[i].height = keyhigh*2 + PADDINGH;
        !           704:             }
        !           705: 
        !           706:         switch (hpkeys[i].code) {
        !           707:             case kZERO:  case kONE:  case kTWO:  case kTHREE:
        !           708:             case kFOUR:  case kFIVE: case kSIX:  case kSEVEN:
        !           709:             case kEIGHT: case kNINE: case kDEC:  case kNEG:
        !           710:            case kBKSP: case kEE:
        !           711:                 key[i].fore=NKeyFore;
        !           712:                 key[i].back=NKeyBack;
        !           713:                 break;
        !           714:             case kADD:   case kSUB:  case kMUL:  case kDIV:  case kENTR:
        !           715:                 key[i].fore=OKeyFore;
        !           716:                 key[i].back=OKeyBack;
        !           717:                 break;
        !           718:             default:
        !           719:                 key[i].fore=FKeyFore;
        !           720:                 key[i].back=FKeyBack;
        !           721:             }
        !           722:        key[i].wid=XCreateSimpleWindow(dpy,theWindow,key[i].x,key[i].y,
        !           723:                                       key[i].width,key[i].height,1,
        !           724:                                       key[i].fore,key[i].back);
        !           725:         }
        !           726:     dispwid = XCreateSimpleWindow(dpy,theWindow,PADDINGW+keywide,PADDINGH,
        !           727:                                  dispwide-2,disphigh,2,DispFore,DispBack);
        !           728: }
        !           729: 
        !           730: 
        !           731: /**************/
        !           732: DrawDisplay()
        !           733: {
        !           734:     int strwide;
        !           735: 
        !           736:     if (strlen(dispstr)>12) {       /* strip out some decimal digits */
        !           737:         char tmp[32];
        !           738:         char *exp = index(dispstr,'e');  /* search for exponent part */
        !           739:         if (!exp) dispstr[12]='\0';      /* no exp, just trunc. */
        !           740:         else {
        !           741:             if (strlen(exp)<=4) 
        !           742:                 sprintf(tmp,"%.8s",dispstr); /* leftmost 8 chars */
        !           743:             else
        !           744:                 sprintf(tmp,"%.7s",dispstr); /* leftmost 7 chars */
        !           745:             strcat (tmp,exp);            /* plus exponent */
        !           746:             strcpy (dispstr,tmp);
        !           747:             }
        !           748:         }
        !           749: 
        !           750:     strwide=XTextWidth(dfontinfo,dispstr,strlen(dispstr));
        !           751: 
        !           752:     XFillRectangle(dpy,dispwid,dispfgc,0,0,10,disphigh);
        !           753:     XFillRectangle(dpy,dispwid,dispfgc,dispwide-10,0,dispwide,disphigh);
        !           754:     XFillRectangle(dpy,dispwid,dispbgc,10,0,dispwide-20,disphigh);
        !           755: 
        !           756:     XDrawString(dpy,dispwid,dispfgc,dispwide-10-DISPPADW/2-strwide,
        !           757:                DISPPADH/2+dfontinfo->ascent,dispstr,strlen(dispstr));
        !           758: 
        !           759:     if (flagM)                XDrawString(dpy,dispwid,flaggc,12,10,"M",1);
        !           760:     if (flagE)                XDrawString(dpy,dispwid,flaggc,12,20,"E",1);
        !           761:     if (flagK)         XDrawString(dpy,dispwid,flaggc,20,disphigh-2,"K",1);
        !           762:     if (flagINV)       XDrawString(dpy,dispwid,flaggc,30,disphigh-2,"INV",3);
        !           763:     if (drgmode==DEG)  XDrawString(dpy,dispwid,flaggc,60,disphigh-2,"DEG",3);
        !           764:     if (drgmode==RAD)  XDrawString(dpy,dispwid,flaggc,80,disphigh-2,"RAD",3);
        !           765:     if (drgmode==GRAD) XDrawString(dpy,dispwid,flaggc,100,disphigh-2,"GRAD",4);
        !           766:     if (flagPAREN)     XDrawString(dpy,dispwid,flaggc,130,disphigh-2,"( )",3);
        !           767: }
        !           768: 
        !           769: 
        !           770: /***************/
        !           771: DrawKey(keynum)
        !           772:     int keynum;
        !           773: {
        !           774:     char *str;
        !           775:     int strwide,extrapad;
        !           776:     struct _key *kp;
        !           777: 
        !           778:     kp = &key[keynum];
        !           779:     str = kp->st;
        !           780:     strwide = XTextWidth(kfontinfo,str,strlen(str));
        !           781: 
        !           782:     extrapad = (keynum>=15 || rpn) ? EXTRAH : 0;
        !           783:     if (rpn && kp->code == kENTR)
        !           784:       extrapad = keyhigh;
        !           785: 
        !           786:     XDrawString(dpy,kp->wid,keygc,(kp->width-strwide)/2,
        !           787:                KEYPADH/2+extrapad+kfontinfo->ascent,str,strlen(str));
        !           788: }
        !           789: 
        !           790: 
        !           791: /*********************************/
        !           792: InvertKey(keynum)
        !           793:     int keynum;
        !           794: {
        !           795:     struct _key *kp;
        !           796: 
        !           797:     kp = &key[keynum];
        !           798:     
        !           799:     XFillRectangle(dpy, kp->wid, keyigc, 0, 0, kp->width, kp->height);
        !           800: }
        !           801: 
        !           802: 
        !           803: /* This section is all of the state machine that implements the calculator
        !           804:  * functions.  Much of it is shared between the infix and rpn modes.
        !           805:  */
        !           806: 
        !           807: static double drg2rad=PI/180.0;  /* Conversion factors for trig funcs */
        !           808: static double rad2drg=180.0/PI;
        !           809: static int entered=1;  /* true if display contains a valid number.
        !           810:                           if==2, then use 'dnum', rather than the string
        !           811:                           stored in the display.  (for accuracy) 
        !           812:                           if==3, then error occurred, only CLR & AC work */
        !           813: static int clear  =0;  /* CLR clears display.  if 1, clears acc, also */
        !           814: static int off    =0;  /* once clears mem, twice quits */
        !           815: static int decimal=0;  /* to prevent using decimal pt twice in a # */
        !           816: static int clrdisp=1;  /* if true clears display before entering # */
        !           817: static int accset =0;
        !           818: static int lastop =kCLR;
        !           819: static int memop  =kCLR;
        !           820: static int exponent=0;
        !           821: static double acc =0.0;
        !           822: static double dnum=0.0;
        !           823: static double mem[10] = { 0.0 };
        !           824: 
        !           825: /*********************************/
        !           826: LetGoKey(keynum)
        !           827:      int keynum;
        !           828: {
        !           829:     int i;
        !           830:     int code;
        !           831: 
        !           832:     if (keynum==-1) return;
        !           833:  
        !           834:     errno = 0;                 /* for non-IEEE machines */
        !           835: 
        !           836:     InvertKey(keynum);
        !           837: 
        !           838:     if ( (entered==3) && !(key[keynum].code==kCLR || key[keynum].code==kOFF)) {
        !           839:       if (rpn) {
        !           840:        clrdisp++;
        !           841:       } else {
        !           842:         XBell(dpy, 0);
        !           843:         return;
        !           844:       }
        !           845:     }
        !           846: 
        !           847:     code = key[keynum].code;
        !           848:     if (code != kCLR) clear=0;
        !           849:     if (code != kOFF) off=0;
        !           850: 
        !           851: 
        !           852: #ifndef IEEE
        !           853:     i=setjmp(env);
        !           854:     if (i) {
        !           855:         switch (i) {
        !           856: #ifdef FPE_FLTDIV_TRAP
        !           857:            case FPE_FLTDIV_TRAP:  strcpy(dispstr,"div by zero"); break;
        !           858: #endif
        !           859: #ifdef FPE_FLTDIV_FAULT
        !           860:            case FPE_FLTDIV_FAULT: strcpy(dispstr,"div by zero"); break;
        !           861: #endif
        !           862: #ifdef FPE_FLTOVF_TRAP
        !           863:            case FPE_FLTOVF_TRAP:  strcpy(dispstr,"overflow"); break;
        !           864: #endif
        !           865: #ifdef FPE_FLTOVF_FAULT
        !           866:            case FPE_FLTOVF_FAULT: strcpy(dispstr,"overflow"); break;
        !           867: #endif
        !           868: #ifdef FPE_FLTUND_TRAP
        !           869:            case FPE_FLTUND_TRAP:  strcpy(dispstr,"underflow"); break;
        !           870: #endif
        !           871: #ifdef FPE_FLTUND_FAULT
        !           872:            case FPE_FLTUND_FAULT: strcpy(dispstr,"underflow"); break;
        !           873: #endif
        !           874:            default:               strcpy(dispstr,"error");
        !           875:            }
        !           876:         entered=3;
        !           877:         DrawDisplay();
        !           878:         return;
        !           879:         }
        !           880: #endif
        !           881: 
        !           882:     (key[keynum].fun)(keynum);
        !           883:     memop = code;
        !           884: 
        !           885: #ifndef IEEE
        !           886:     if (errno) {
        !           887:         strcpy(dispstr,"error");
        !           888:         DrawDisplay();
        !           889:         entered=3;
        !           890:         errno=0;
        !           891:         }
        !           892: #endif
        !           893: }
        !           894: 
        !           895: 
        !           896: digit(keynum)
        !           897:      int keynum;
        !           898: {
        !           899:   flagINV=0;
        !           900:   if (rpn && (memop == kSTO || memop == kRCL || memop == kSUM)) {
        !           901:       switch (memop) {
        !           902:       case kSTO: mem[*(key[keynum].st) - '0'] = dnum; break;
        !           903:       case kRCL: dnum = mem[*(key[keynum].st) - '0'];
        !           904:                 sprintf(dispstr, "%.8g", dnum);
        !           905:                 break;
        !           906:       case kSUM: mem[*(key[keynum].st) - '0'] += dnum; break;
        !           907:       }
        !           908:       DrawDisplay();
        !           909:       entered = 2;
        !           910:       clrdisp++;
        !           911:       return;
        !           912:   }
        !           913:   if (clrdisp) {
        !           914:     dispstr[0]='\0';
        !           915:     exponent=decimal=0;
        !           916:     if (rpn && entered==2)
        !           917:       PushNum(dnum);
        !           918:   }
        !           919:   if (strlen(dispstr)>=MAXDISP)
        !           920:     return;
        !           921:   strcat(dispstr,key[keynum].st);
        !           922:   DrawDisplay();
        !           923:   if (clrdisp && key[keynum].code != kZERO)
        !           924:     clrdisp=0; /*no leading 0s*/
        !           925:   entered=1;
        !           926: }
        !           927: 
        !           928: bkspf()
        !           929: {
        !           930:   if (entered!=1 || clrdisp)
        !           931:     return;
        !           932:   if (strlen(dispstr) > 0)
        !           933:     dispstr[strlen(dispstr)-1] = 0;
        !           934:   if (strlen(dispstr) == 0) {
        !           935:     strcat(dispstr, "0");
        !           936:     clrdisp++;
        !           937:   }
        !           938:   DrawDisplay();
        !           939: }
        !           940: 
        !           941: decf()
        !           942: {
        !           943:   flagINV=0;
        !           944:   if (clrdisp) {
        !           945:       if (rpn)
        !           946:        PushNum(dnum);
        !           947:       strcpy(dispstr,"0");
        !           948:   }
        !           949:   if (!decimal) {
        !           950:     strcat(dispstr,".");
        !           951:     DrawDisplay();
        !           952:     decimal++;
        !           953:   }
        !           954:   clrdisp=0;
        !           955:   entered=1;
        !           956: }
        !           957: 
        !           958: eef()
        !           959: {
        !           960:   flagINV=0;
        !           961:   if (clrdisp) {
        !           962:       if (rpn)
        !           963:        PushNum(dnum);
        !           964:       strcpy(dispstr, rpn ? "1" : "0");
        !           965:   }
        !           966:   if (!exponent) {
        !           967:     strcat(dispstr,"E+");
        !           968:     DrawDisplay();
        !           969:     exponent=strlen(dispstr)-1;  /* where the '-' goes */
        !           970:   }
        !           971:   clrdisp=0;
        !           972:   entered=1;
        !           973: }
        !           974: 
        !           975: clearf()
        !           976: {
        !           977:   flagINV=0;
        !           978:   if (clear && !rpn) { /* clear all */
        !           979:     ClearStacks();
        !           980:     flagPAREN=0;
        !           981:   }
        !           982:   clear++;
        !           983:   exponent=decimal=0;
        !           984:   clrdisp=1;
        !           985:   entered=1;
        !           986:   strcpy(dispstr,"0");
        !           987:   DrawDisplay();
        !           988: }
        !           989: 
        !           990: negf()
        !           991: {
        !           992:   flagINV=0;
        !           993:   if (exponent) {       /* neg the exponent */
        !           994:     if (dispstr[exponent]=='-')
        !           995:       dispstr[exponent]='+';
        !           996:     else
        !           997:       dispstr[exponent]='-';
        !           998:     DrawDisplay();
        !           999:     return;
        !          1000:   }
        !          1001: 
        !          1002:   if (strcmp("0",dispstr)==0)
        !          1003:     return;                    /* don't neg a zero */
        !          1004:   if (dispstr[0]=='-')         /* already neg-ed */
        !          1005:     strcpy(dispstr,dispstr+1);  /* move str left once */
        !          1006:   else {                       /* not neg-ed.  add a '-' */
        !          1007:     char tmp[32];
        !          1008:     sprintf(tmp,"-%s",dispstr);
        !          1009:     strcpy(dispstr,tmp);
        !          1010:   }
        !          1011:   if (entered==2)
        !          1012:     dnum = -1.0 * dnum;
        !          1013:   DrawDisplay();
        !          1014: }
        !          1015: 
        !          1016: /* Two operand functions for infix calc */
        !          1017: twoop(keynum)
        !          1018: {
        !          1019:   double PopNum();
        !          1020: 
        !          1021:   if (flagINV) {
        !          1022:     flagINV=0;
        !          1023:     DrawDisplay();
        !          1024:   }
        !          1025: 
        !          1026:   if (!entered) {              /* something like "5+*" */
        !          1027:     if (!isopempty())
        !          1028:       PopOp();                 /* replace the prev op */
        !          1029:     PushOp(key[keynum].code);  /* with the new one */
        !          1030:     return;
        !          1031:   }
        !          1032:   
        !          1033:   if (entered==1)
        !          1034:     sscanf(dispstr,"%lf",&dnum);
        !          1035: 
        !          1036:   clrdisp=clear=1;
        !          1037:   entered=decimal=exponent=0;
        !          1038: 
        !          1039:   if (!isopempty()) {  /* there was a previous op */
        !          1040:     lastop=PopOp();   /* get it */
        !          1041: 
        !          1042:     if (lastop==kLPAR) {  /* put it back */
        !          1043:       PushOp(kLPAR);
        !          1044:       PushOp(key[keynum].code);
        !          1045:       PushNum(dnum);
        !          1046:       return;
        !          1047:     }
        !          1048: 
        !          1049:     /* now, if the current op (keynum) is of
        !          1050:        higher priority than the lastop, the current
        !          1051:        op and number are just pushed on top 
        !          1052:        Priorities:  (Y^X) > *,/ > +,- */
        !          1053:     
        !          1054:     if (priority(key[keynum].code) > priority(lastop)) {
        !          1055:       PushNum(dnum);
        !          1056:       PushOp(lastop);
        !          1057:       PushOp(key[keynum].code);
        !          1058:     } else {  /* execute lastop on lastnum and dnum, push
        !          1059:               result and current op on stack */
        !          1060:       acc=PopNum();
        !          1061:       switch (lastop) { /* perform the operation */
        !          1062:       case kADD: acc += dnum;  break;
        !          1063:       case kSUB: acc -= dnum;  break;
        !          1064:       case kMUL: acc *= dnum;  break;
        !          1065:       case kDIV: acc /= dnum;  break;
        !          1066:       case kPOW: acc =  pow(acc,dnum);  break;
        !          1067:        }
        !          1068:       PushNum(acc);
        !          1069:       PushOp(key[keynum].code);
        !          1070:       sprintf(dispstr,"%.8g",acc);
        !          1071:       DrawDisplay();
        !          1072:       dnum=acc;
        !          1073:     }
        !          1074:   }
        !          1075:   else { /* op stack is empty, push op and num */
        !          1076:     PushOp(key[keynum].code);
        !          1077:     PushNum(dnum);
        !          1078:   } 
        !          1079: }                      
        !          1080: 
        !          1081: /* Two operand functions for rpn calc */
        !          1082: twof(keynum)
        !          1083: {
        !          1084:   double PopNum();
        !          1085: 
        !          1086:   if (flagINV) {
        !          1087:     flagINV=0;
        !          1088:     DrawDisplay();
        !          1089:   }
        !          1090:   if (!entered)
        !          1091:     return;
        !          1092:   if (entered==1)
        !          1093:     sscanf(dispstr, "%lf", &dnum);
        !          1094:   acc = PopNum();
        !          1095:   switch(key[keynum].code) {
        !          1096:   case kADD: acc += dnum;  break;
        !          1097:   case kSUB: acc -= dnum;  break;
        !          1098:   case kMUL: acc *= dnum;  break;
        !          1099:   case kDIV: acc /= dnum;  break;
        !          1100:   case kPOW: acc =  pow(acc,dnum);  break;
        !          1101:   case kXXY: PushNum(dnum);
        !          1102:   }
        !          1103:   sprintf(dispstr, "%.8g", acc);
        !          1104:   DrawDisplay();
        !          1105:   clrdisp++;
        !          1106:   decimal = exponent = 0;
        !          1107:   entered = 2;
        !          1108:   dnum = acc;
        !          1109: }
        !          1110: 
        !          1111: 
        !          1112: entrf()
        !          1113: {
        !          1114:   flagINV=0;
        !          1115:   if (!entered)
        !          1116:     return;
        !          1117: 
        !          1118:   clrdisp=clear=1;
        !          1119:   decimal=exponent=0;
        !          1120: 
        !          1121:   if (entered==1)
        !          1122:     sscanf(dispstr,"%lf",&dnum);
        !          1123:   entered=2;
        !          1124: 
        !          1125:   if (entered==2)
        !          1126:     PushNum(dnum);
        !          1127: }
        !          1128: 
        !          1129: equf()
        !          1130: {
        !          1131:   double PopNum();
        !          1132: 
        !          1133:   flagINV=0;
        !          1134:   if (!entered)
        !          1135:     return;
        !          1136: 
        !          1137:   clrdisp=clear=1;
        !          1138:   decimal=exponent=0;
        !          1139: 
        !          1140:   if (entered==1)
        !          1141:     sscanf(dispstr,"%lf",&dnum);
        !          1142:   entered=2;
        !          1143: 
        !          1144:   PushNum(dnum);
        !          1145: 
        !          1146:   while (!isopempty()) {  /* do all pending ops */
        !          1147:     dnum=PopNum();
        !          1148:     acc=PopNum();
        !          1149:     lastop=PopOp();
        !          1150:     switch (lastop) {
        !          1151:     case kADD:  acc += dnum;
        !          1152:                break;
        !          1153:     case kSUB:  acc -= dnum;
        !          1154:                break;
        !          1155:     case kMUL:  acc *= dnum;
        !          1156:                break;
        !          1157:     case kDIV:  acc /= dnum;
        !          1158:                break;
        !          1159:     case kPOW:  acc = pow(acc,dnum);
        !          1160:                break;
        !          1161:     case kLPAR:        flagPAREN--;
        !          1162:                PushNum(acc);
        !          1163:                break;
        !          1164:     }
        !          1165:     dnum=acc;
        !          1166:     PushNum(dnum);
        !          1167:   }
        !          1168: 
        !          1169:   sprintf(dispstr,"%.8g",dnum);
        !          1170:   DrawDisplay();
        !          1171: }
        !          1172:         
        !          1173: lparf()
        !          1174: {
        !          1175:   flagINV=0;
        !          1176:   PushOp(kLPAR);
        !          1177:   flagPAREN++;
        !          1178:   DrawDisplay();
        !          1179: }
        !          1180: 
        !          1181: rollf()
        !          1182: {
        !          1183:   double PopNum();
        !          1184: 
        !          1185:   if (!entered)
        !          1186:     return;
        !          1187:   if (entered==1)
        !          1188:     sscanf(dispstr, "%lf", &dnum);
        !          1189:   entered = 2;
        !          1190:   RollNum(flagINV);
        !          1191:   flagINV=0;
        !          1192:   clrdisp++;
        !          1193:   sprintf(dispstr, "%.8g", dnum);
        !          1194:   DrawDisplay();
        !          1195: }
        !          1196: 
        !          1197: rparf()
        !          1198: {
        !          1199:   double PopNum();
        !          1200: 
        !          1201:   flagINV=0;
        !          1202:   if (!entered)
        !          1203:     return;
        !          1204: 
        !          1205:   if (!flagPAREN)
        !          1206:     return;
        !          1207:   
        !          1208:   clrdisp++;
        !          1209:   decimal=exponent=0;
        !          1210: 
        !          1211:   if (entered==1)
        !          1212:     sscanf(dispstr,"%lf",&dnum);
        !          1213:   entered=2;
        !          1214: 
        !          1215:   PushNum(dnum);
        !          1216:   while (!isopempty() && (lastop=PopOp())!=kLPAR) {
        !          1217:     /* do all pending ops, back to left paren */
        !          1218:     dnum=PopNum();
        !          1219:     acc=PopNum();
        !          1220:     switch (lastop) {
        !          1221:     case kADD:  acc += dnum;
        !          1222:                break;
        !          1223:     case kSUB:  acc -= dnum;
        !          1224:                break;
        !          1225:     case kMUL:  acc *= dnum;
        !          1226:                break;
        !          1227:     case kDIV:  acc /= dnum;
        !          1228:                break;
        !          1229:     case kPOW:  acc = pow(acc,dnum);
        !          1230:                break;
        !          1231:     }
        !          1232:     dnum=acc;
        !          1233:     PushNum(dnum);
        !          1234:   }
        !          1235:   PopNum();
        !          1236:   flagPAREN--;
        !          1237:   entered=2;
        !          1238:   sprintf(dispstr,"%.8g",dnum);
        !          1239:   DrawDisplay();
        !          1240: }
        !          1241: 
        !          1242: drgf()
        !          1243: {
        !          1244:   if (flagINV) {
        !          1245:     if (entered==1)
        !          1246:       sscanf(dispstr,"%lf",&dnum);
        !          1247:     switch (drgmode) {
        !          1248:     case DEG:  dnum=dnum*PI/180.0;    break;
        !          1249:     case RAD:  dnum=dnum*200.0/PI;    break;
        !          1250:     case GRAD: dnum=dnum*90.0/100.0;  break;
        !          1251:     }
        !          1252:     entered=2;
        !          1253:     clrdisp=1;
        !          1254:     flagINV=0;
        !          1255:     sprintf(dispstr,"%.8g",dnum);
        !          1256:   }
        !          1257:                          
        !          1258:   flagINV=0;
        !          1259:   drgmode = ++drgmode % 3;
        !          1260:   switch (drgmode) {
        !          1261:   case DEG:  drg2rad=PI / 180.0;
        !          1262:             rad2drg=180.0 / PI;
        !          1263:             break;
        !          1264:   case RAD:  drg2rad=1.0;
        !          1265:             rad2drg=1.0;
        !          1266:             break;
        !          1267:   case GRAD: drg2rad=PI / 200.0;
        !          1268:             rad2drg=200.0 / PI;
        !          1269:             break;
        !          1270:   }
        !          1271:   DrawDisplay();
        !          1272: }
        !          1273: 
        !          1274: invf()
        !          1275: {
        !          1276:   flagINV = ~flagINV;
        !          1277:   DrawDisplay();
        !          1278: }
        !          1279: 
        !          1280: memf(keynum)
        !          1281: {
        !          1282:     if (entered==1)
        !          1283:       sscanf(dispstr,"%lf",&dnum);
        !          1284:     entered = 2;
        !          1285:     clrdisp++;
        !          1286: }
        !          1287: 
        !          1288: oneop(keynum)
        !          1289: {
        !          1290:   int i,j;
        !          1291:   double dtmp;
        !          1292: 
        !          1293:   if (entered==1)
        !          1294:     sscanf(dispstr,"%lf",&dnum);
        !          1295:   entered = 2;
        !          1296: 
        !          1297:   switch (key[keynum].code) {  /* do the actual math fn. */
        !          1298:   case kE:     if (rpn && memop != kENTR) PushNum(dnum); dnum=E;  break;
        !          1299:   case kPI:    if (rpn && memop != kENTR) PushNum(dnum); dnum=PI;  break;
        !          1300:   case kRECIP: dnum=1.0/dnum;  break;
        !          1301:   case kSQR:   flagINV = !flagINV; /* fall through to */
        !          1302:   case kSQRT:  if (flagINV) dnum=dnum*dnum;
        !          1303:               else dnum=sqrt(dnum);
        !          1304:               break;
        !          1305:   case k10X:   flagINV = !flagINV; /* fall through to */
        !          1306:   case kLOG:   if (flagINV) dnum=pow(10.0,dnum);
        !          1307:               else dnum=log10(dnum);
        !          1308:               break;
        !          1309:   case kEXP:   flagINV = !flagINV; /* fall through to */
        !          1310:   case kLN:    if (flagINV) dnum=exp(dnum);
        !          1311:               else dnum=log(dnum);
        !          1312:               break;
        !          1313:   case kSIN:   if (flagINV) dnum=asin(dnum)*rad2drg;
        !          1314:               else dnum=sin(dnum*drg2rad);
        !          1315:               break;
        !          1316:   case kCOS:   if (flagINV) dnum=acos(dnum)*rad2drg;
        !          1317:               else dnum=cos(dnum*drg2rad);
        !          1318:               break;
        !          1319:   case kTAN:   if (flagINV) dnum=atan(dnum)*rad2drg;
        !          1320:               else dnum=tan(dnum*drg2rad);
        !          1321:               break;
        !          1322:   case kSTO:   mem[0]=dnum;  flagM=!(mem[0]==0.0);  break;
        !          1323:   case kRCL:   dnum=mem[0];  flagM=!(mem[0]==0.0);  break;
        !          1324:   case kSUM:   mem[0]+=dnum; flagM=!(mem[0]==0.0);  break;
        !          1325:   case kEXC:   dtmp=dnum; dnum=mem[0];  mem[0]=dtmp;
        !          1326:               flagM=!(mem[0]==0.0);  break;
        !          1327:   case kFACT:  if (floor(dnum)!=dnum || dnum<0.0 || dnum>500.0) {
        !          1328:                 strcpy(dispstr,"error");
        !          1329:                 entered=3;
        !          1330:                 break;
        !          1331:               }
        !          1332:               i=(int) (floor(dnum));
        !          1333:               for (j=1,dnum=1.0; j<=i; j++) 
        !          1334:                 dnum*=(float) j;
        !          1335:               break;
        !          1336:   }
        !          1337:   
        !          1338:   if (entered==3) {  /* error */
        !          1339:     DrawDisplay();
        !          1340:     return;
        !          1341:   }
        !          1342: 
        !          1343:   entered=2;
        !          1344:   clrdisp=1;
        !          1345:   flagINV=0;
        !          1346:   sprintf(dispstr,"%.8g",dnum);
        !          1347:   DrawDisplay();
        !          1348: }
        !          1349: 
        !          1350: offf()
        !          1351: {
        !          1352:   /* full reset */
        !          1353:   ResetCalc();
        !          1354:   entered=clrdisp=1;
        !          1355:   dnum=mem[0]=0.0;
        !          1356:   accset=exponent=decimal=0;
        !          1357:   DrawDisplay();
        !          1358: }
        !          1359: 
        !          1360: 
        !          1361: nop()
        !          1362: {
        !          1363:   XBell(dpy, 0);
        !          1364: }
        !          1365: 
        !          1366: 
        !          1367: /*******/
        !          1368: Quit()
        !          1369: /*******/
        !          1370: {
        !          1371:     exit(0);
        !          1372: }
        !          1373: 
        !          1374: 
        !          1375: #define STACKMAX 32
        !          1376: static int opstack[STACKMAX];
        !          1377: static int opsp;
        !          1378: static double numstack[STACKMAX];
        !          1379: static int numsp;
        !          1380: 
        !          1381: 
        !          1382: /*******/
        !          1383: PushOp(op)
        !          1384:    int op;
        !          1385: /*******/
        !          1386: {
        !          1387:   if (opsp==STACKMAX) {strcpy(dispstr,"stack error");  entered=3;}
        !          1388:   else opstack[opsp++]=op;
        !          1389: }
        !          1390: 
        !          1391: /*******/
        !          1392: int PopOp()
        !          1393: /*******/
        !          1394: {
        !          1395:   if (opsp==0) {
        !          1396:       strcpy(dispstr,"stack error");
        !          1397:       entered=3;
        !          1398:       return(kNOP);
        !          1399:   } else
        !          1400:     return(opstack[--opsp]);
        !          1401: }
        !          1402: 
        !          1403: /*******/
        !          1404: int isopempty()
        !          1405: /*******/
        !          1406: {
        !          1407:   return( opsp ? 0 : 1 );
        !          1408: }
        !          1409: 
        !          1410: /*******/
        !          1411: PushNum(num)
        !          1412:  double num;
        !          1413: /*******/
        !          1414: {
        !          1415:   if (rpn) {
        !          1416:       numstack[2] = numstack[1];
        !          1417:       numstack[1] = numstack[0];
        !          1418:       numstack[0] = num;
        !          1419:       return;
        !          1420:   }
        !          1421:   if (numsp==STACKMAX) {
        !          1422:       strcpy(dispstr,"stack error");
        !          1423:       entered=3;
        !          1424:   } else
        !          1425:     numstack[numsp++]=num;
        !          1426: }
        !          1427: 
        !          1428: /*******/
        !          1429: double PopNum()
        !          1430: /*******/
        !          1431: {
        !          1432:     if (rpn) {
        !          1433:        double tmp = numstack[0];
        !          1434:        numstack[0] = numstack[1];
        !          1435:        numstack[1] = numstack[2];
        !          1436:        return(tmp);
        !          1437:     }
        !          1438:     if (numsp==0) {
        !          1439:        strcpy(dispstr,"stack error");
        !          1440:        entered=3;
        !          1441:     } else
        !          1442:       return(numstack[--numsp]);
        !          1443: }
        !          1444: 
        !          1445: /*******/
        !          1446: RollNum(dir)
        !          1447: /*******/
        !          1448: {
        !          1449:     double tmp;
        !          1450: 
        !          1451:     if (!dir) {
        !          1452:        tmp         = dnum;
        !          1453:        dnum        = numstack[2];
        !          1454:        numstack[2] = numstack[1];
        !          1455:        numstack[1] = numstack[0];
        !          1456:        numstack[0] = tmp;
        !          1457:     } else {
        !          1458:        tmp         = dnum;
        !          1459:        dnum        = numstack[0];
        !          1460:        numstack[0] = numstack[1];
        !          1461:        numstack[1] = numstack[2];
        !          1462:        numstack[2] = tmp;
        !          1463:     }
        !          1464: }
        !          1465: 
        !          1466: 
        !          1467: /*******/
        !          1468: int isnumempty()
        !          1469: /*******/
        !          1470: {
        !          1471:   return( numsp ? 0 : 1 );
        !          1472: }
        !          1473: 
        !          1474: 
        !          1475: /*******/
        !          1476: ClearStacks()
        !          1477: /*******/
        !          1478: {
        !          1479:     if (rpn)
        !          1480:       numstack[0] = numstack[1] = numstack[2] = 0.;
        !          1481:     opsp=numsp=0;
        !          1482: }
        !          1483: 
        !          1484: 
        !          1485: /*******/
        !          1486: int priority(op)
        !          1487:          int op;
        !          1488: /*******/
        !          1489: {
        !          1490:     switch (op) {
        !          1491:         case kPOW: return(2);
        !          1492:         case kMUL:
        !          1493:         case kDIV: return(1);
        !          1494:         case kADD:
        !          1495:         case kSUB: return(0);
        !          1496:         }
        !          1497: }
        !          1498: 
        !          1499: 
        !          1500: /********/
        !          1501: ResetCalc()
        !          1502: /********/
        !          1503: {
        !          1504:     flagM=flagK=flagINV=flagE=flagPAREN=0;  drgmode=DEG;
        !          1505:     strcpy(dispstr,"0");
        !          1506:     ClearStacks();
        !          1507:     drg2rad=PI/180.0;
        !          1508:     rad2drg=180.0/PI;
        !          1509: }
        !          1510: 
        !          1511: 
        !          1512: /*********/
        !          1513: TypeChar(c)
        !          1514:     char c;
        !          1515: /*********/
        !          1516: {
        !          1517:     /* figure out if person typed a valid calculator key.
        !          1518:          If so, press the key, wait a bit, and release the key
        !          1519:          else Feep() */
        !          1520: 
        !          1521:     int i,code;
        !          1522: 
        !          1523:     switch (c) {
        !          1524:         case '0':  code=kZERO;   break;
        !          1525:         case '1':  code=kONE;    break;
        !          1526:         case '2':  code=kTWO;    break;
        !          1527:         case '3':  code=kTHREE;  break;
        !          1528:         case '4':  code=kFOUR;   break;
        !          1529:         case '5':  code=kFIVE;   break;
        !          1530:         case '6':  code=kSIX;    break;
        !          1531:         case '7':  code=kSEVEN;  break;
        !          1532:         case '8':  code=kEIGHT;  break;
        !          1533:         case '9':  code=kNINE;   break;
        !          1534:         case '.':  code=kDEC;    break;
        !          1535:         case '+':  code=kADD;    break;
        !          1536:         case '-':  code=kSUB;    break;
        !          1537:         case '*':  code=kMUL;    break;
        !          1538:         case '/':  code=kDIV;    break;
        !          1539:         case '(':  code=kLPAR;   break;
        !          1540:         case ')':  code=kRPAR;   break;
        !          1541:         case '!':  code=kFACT;   break;
        !          1542:         case 'e':  code=kEE;     break;
        !          1543:         case '^':  code=kPOW;    break;
        !          1544:         case 'p':  code=kPI;     break;
        !          1545:         case 'i':  code=kINV;    break;
        !          1546:         case 's':  code=kSIN;    break;
        !          1547:         case 'c':  code=kCOS;    break;
        !          1548:         case 't':  code=kTAN;    break;
        !          1549:         case 'd':  code=kDRG;    break;
        !          1550:         case 'l':  code=kLN;     break;
        !          1551:         case '=':  code=kEQU;    break;
        !          1552:         case 'n':  code=kNEG;    break;
        !          1553:        case 'r':  code=kSQRT;   break;
        !          1554:        case 'x':  code=kXXY;    break;
        !          1555:        case '\r':
        !          1556:        case '\n': code=kENTR;   break;
        !          1557:         case '\177':
        !          1558:         case '\010': code=kBKSP; break;
        !          1559:        case ' ':  code=kCLR;    break;
        !          1560:         case '\003': Quit();     break;
        !          1561:         default:   code = -1;
        !          1562:         }
        !          1563: 
        !          1564:     if (!rpn && code == kBKSP)
        !          1565:       code = kCLR;
        !          1566:     for (i=0; i < numkeys; i++)
        !          1567:       if (key[i].code == code) break;
        !          1568: 
        !          1569:     if (code != -1 && i < numkeys && key[i].code == code) {
        !          1570:         InvertKey(i);
        !          1571:         XFlush(dpy);
        !          1572:         Timer(100000L);
        !          1573:         LetGoKey(i);
        !          1574:         XFlush(dpy);
        !          1575:         }
        !          1576:     else XBell(dpy,0);
        !          1577: }
        !          1578: 
        !          1579: 
        !          1580: 
        !          1581: static int timerdone;
        !          1582: 
        !          1583: /*******/
        !          1584: onalarm()
        !          1585: /*******/
        !          1586: {
        !          1587:   timerdone=1;
        !          1588: }
        !          1589: 
        !          1590: /*******/
        !          1591: Timer(val)
        !          1592:  long val;
        !          1593: /*******/
        !          1594: {
        !          1595:         struct itimerval it;
        !          1596: 
        !          1597:         bzero(&it, sizeof(it));
        !          1598:         it.it_value.tv_usec = val;
        !          1599:         timerdone=0;
        !          1600:         signal(SIGALRM,onalarm);
        !          1601:         setitimer(ITIMER_REAL, &it, (struct itimerval *)0);
        !          1602:         while (!timerdone);
        !          1603:         signal(SIGALRM,SIG_DFL);
        !          1604: }
        !          1605: 
        !          1606: 
        !          1607: 
        !          1608: #ifndef IEEE
        !          1609: /******************/
        !          1610: fperr(sig,code,scp)
        !          1611:   int sig,code;
        !          1612:   struct sigcontext *scp;
        !          1613: /******************/
        !          1614: {
        !          1615:     longjmp(env,code);
        !          1616: }
        !          1617: 
        !          1618: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.