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

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

unix.superglobalmegacorp.com

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