Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2 
      3 Copyright (c) 1989  X Consortium
      4 
      5 Permission is hereby granted, free of charge, to any person obtaining
      6 a copy of this software and associated documentation files (the
      7 "Software"), to deal in the Software without restriction, including
      8 without limitation the rights to use, copy, modify, merge, publish,
      9 distribute, sublicense, and/or sell copies of the Software, and to
     10 permit persons to whom the Software is furnished to do so, subject to
     11 the following conditions:
     12 
     13 The above copyright notice and this permission notice shall be included
     14 in all copies or substantial portions of the Software.
     15 
     16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     17 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     19 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22 OTHER DEALINGS IN THE SOFTWARE.
     23 
     24 Except as contained in this notice, the name of the X Consortium shall
     25 not be used in advertising or otherwise to promote the sale, use or
     26 other dealings in this Software without prior written authorization
     27 from the X Consortium.
     28 
     29 */
     30 
     31 /*
     32  * actions.c - externally available procedures for xcalc
     33  *
     34  * Author:  Donna Converse, MIT X Consortium
     35  */
     36 
     37 #include <X11/Intrinsic.h>
     38 #include <setjmp.h>
     39 #include "xcalc.h"
     40 
     41 #ifndef IEEE
     42 #define XCALC_PRE_OP(keynum) { if (pre_op(keynum)) return; \
     43 		       if (setjmp (env)) {fail_op(); return;}}
     44 #else
     45 #define XCALC_PRE_OP(keynum) if (pre_op(keynum)) return;
     46 #endif
     47 
     48 static void add(Widget w, XEvent *ev, String *vector, Cardinal *count);
     49 static void and(Widget w, XEvent *ev, String *vector, Cardinal *count);
     50 static void back(Widget w, XEvent *ev, String *vector, Cardinal *count);
     51 static void base(Widget w, XEvent *ev, String *vector, Cardinal *count);
     52 static void bell(Widget w, XEvent *ev, String *vector, Cardinal *count);
     53 static void clearit(Widget w, XEvent *ev, String *vector, Cardinal *count);
     54 static void cosine(Widget w, XEvent *ev, String *vector, Cardinal *count);
     55 static void decimal(Widget w, XEvent *ev, String *vector, Cardinal *count);
     56 static void degree(Widget w, XEvent *ev, String *vector, Cardinal *count);
     57 static void digit(Widget w, XEvent *ev, String *vector, Cardinal *count);
     58 static void divide(Widget w, XEvent *ev, String *vector, Cardinal *count);
     59 static void e(Widget w, XEvent *ev, String *vector, Cardinal *count);
     60 static void enter(Widget w, XEvent *ev, String *vector, Cardinal *count);
     61 static void epower(Widget w, XEvent *ev, String *vector, Cardinal *count);
     62 static void equal(Widget w, XEvent *ev, String *vector, Cardinal *count);
     63 static void exchange(Widget w, XEvent *ev, String *vector, Cardinal *count);
     64 static void factorial(Widget w, XEvent *ev, String *vector, Cardinal *count);
     65 static void inverse(Widget w, XEvent *ev, String *vector, Cardinal *count);
     66 static void leftParen(Widget w, XEvent *ev, String *vector, Cardinal *count);
     67 static void logarithm(Widget w, XEvent *ev, String *vector, Cardinal *count);
     68 static void mod(Widget w, XEvent *ev, String *vector, Cardinal *count);
     69 static void multiply(Widget w, XEvent *ev, String *vector, Cardinal *count);
     70 static void naturalLog(Widget w, XEvent *ev, String *vector, Cardinal *count);
     71 static void negate(Widget w, XEvent *ev, String *vector, Cardinal *count);
     72 static void nop(Widget w, XEvent *ev, String *vector, Cardinal *count);
     73 static void not(Widget w, XEvent *ev, String *vector, Cardinal *count);
     74 static void off(Widget w, XEvent *ev, String *vector, Cardinal *count);
     75 static void or(Widget w, XEvent *ev, String *vector, Cardinal *count);
     76 static void pi(Widget w, XEvent *ev, String *vector, Cardinal *count);
     77 static void power(Widget w, XEvent *ev, String *vector, Cardinal *count);
     78 static void quit(Widget w, XEvent *ev, String *vector, Cardinal *count);
     79 static void recall(Widget w, XEvent *ev, String *vector, Cardinal *count);
     80 static void reciprocal(Widget w, XEvent *ev, String *vector, Cardinal *count);
     81 static void rightParen(Widget w, XEvent *ev, String *vector, Cardinal *count);
     82 static void roll(Widget w, XEvent *ev, String *vector, Cardinal *count);
     83 static void scientific(Widget w, XEvent *ev, String *vector, Cardinal *count);
     84 static void selection(Widget w, XEvent *ev, String *vector, Cardinal *count);
     85 static void shl(Widget w, XEvent *ev, String *vector, Cardinal *count);
     86 static void shr(Widget w, XEvent *ev, String *vector, Cardinal *count);
     87 static void sine(Widget w, XEvent *ev, String *vector, Cardinal *count);
     88 static void square(Widget w, XEvent *ev, String *vector, Cardinal *count);
     89 static void squareRoot(Widget w, XEvent *ev, String *vector, Cardinal *count);
     90 static void store(Widget w, XEvent *ev, String *vector, Cardinal *count);
     91 static void subtract(Widget w, XEvent *ev, String *vector, Cardinal *count);
     92 static void sum(Widget w, XEvent *ev, String *vector, Cardinal *count);
     93 static void tangent(Widget w, XEvent *ev, String *vector, Cardinal *count);
     94 static void tenpower(Widget w, XEvent *ev, String *vector, Cardinal *count);
     95 static void xtrunc(Widget w, XEvent *ev, String *vector, Cardinal *count);
     96 static void xor(Widget w, XEvent *ev, String *vector, Cardinal *count);
     97 static void XexchangeY(Widget w, XEvent *ev, String *vector, Cardinal *count);
     98 
     99 /*
    100  * 	calculator action table
    101  */
    102 
    103 XtActionsRec	Actions[] = {
    104 {"add",		add},		/* addition */
    105 {"and",		and},		/* bitwise and */
    106 {"back",	back},		/* HP-specific backspace */
    107 {"base",	base},		/* base conversion */
    108 {"bell",	bell},		/* ring bell */
    109 {"clear",	clearit},	/* TI-specific clear calculator state */
    110 {"cosine",	cosine},	/* trigonometric function cosine */
    111 {"decimal",	decimal},	/* decimal point */
    112 {"degree",	degree},	/* degree, radian, grad switch */
    113 {"digit",	digit},		/* numeric key */
    114 {"divide",	divide},	/* division */
    115 {"e",		e},		/* the natural number e */
    116 {"enter",	enter},		/* HP-specific enter */
    117 {"epower",	epower},	/* e raised to a power */
    118 {"equal",	equal},		/* TI-specific = */
    119 {"exchange",	exchange},	/* TI-specific exchange memory and display */
    120 {"factorial",	factorial},	/* factorial function */
    121 {"inverse", 	inverse},	/* inverse */
    122 {"leftParen",	leftParen},	/* TI-specific left parenthesis */
    123 {"logarithm",	logarithm},	/* logarithm base 10 */
    124 {"mod",		mod},		/* modulus */
    125 {"multiply",	multiply},	/* multiplication */
    126 {"naturalLog",	naturalLog},	/* natural logarithm base e */
    127 {"negate",	negate},	/* change sign */
    128 {"nop",		nop},		/* no operation, rings bell */
    129 {"not",		not},		/* bitwise not */
    130 {"off",		off},		/* clear state */
    131 {"or",		or},		/* bitwise or */
    132 {"pi",		pi},		/* the number pi */
    133 {"power",	power},		/* raise to an arbitrary power */
    134 {"quit",	quit},		/* quit */
    135 {"recall",	recall},	/* memory recall */
    136 {"reciprocal",  reciprocal},	/* reciprocal function */
    137 {"rightParen",	rightParen},	/* TI-specific left parenthesis */
    138 {"roll",	roll},		/* HP-specific roll stack */
    139 {"scientific",	scientific},	/* scientific notation (EE) */
    140 {"selection",	selection},	/* copy selection */
    141 {"shl",		shl},		/* arithmetic shift left */
    142 {"shr",		shr},		/* arithmetic shift right */
    143 {"sine",	sine},		/* trigonometric function sine */
    144 {"square",	square},	/* square */
    145 {"squareRoot",	squareRoot},	/* square root */
    146 {"store",	store},		/* memory store */
    147 {"subtract", 	subtract},	/* subtraction */
    148 {"sum",		sum},		/* memory summation */
    149 {"tangent",	tangent},	/* trigonometric function tangent */
    150 {"tenpower",	tenpower},	/* 10 raised to to an arbitrary power */
    151 {"trunc",	xtrunc}, 	/* truncate to integer */
    152 {"xor",		xor},		/* bitwise xor */
    153 {"XexchangeY",	XexchangeY}	/* HP-specific exchange X and Y registers */
    154 };
    155 
    156 int ActionsCount = XtNumber(Actions);
    157 
    158 /*ARGSUSED*/
    159 static void add(Widget w, XEvent *ev, String *vector, Cardinal *count)
    160 {
    161     XCALC_PRE_OP(kADD);
    162     rpn ? twof(kADD) : twoop(kADD);
    163     post_op();
    164 }
    165 
    166 /*ARGSUSED*/
    167 static void and(Widget w, XEvent *ev, String *vector, Cardinal *count)
    168 {
    169     XCALC_PRE_OP(kAND);
    170     rpn ? twof(kAND) : twoop(kAND);
    171     post_op();
    172 }
    173 
    174 /*ARGSUSED*/
    175 static void back(Widget w, XEvent *ev, String *vector, Cardinal *count)
    176 {
    177     XCALC_PRE_OP(kBKSP);
    178     bkspf();
    179     post_op();
    180 }
    181 
    182 /*ARGSUSED*/
    183 static void base(Widget w, XEvent *ev, String *vector, Cardinal *count)
    184 {
    185     XCALC_PRE_OP(kBASE);
    186     change_base();
    187     post_op();
    188 }
    189 
    190 /*ARGSUSED*/
    191 static void bell(Widget w, XEvent *ev, String *vector, Cardinal *count)
    192 {
    193     ringbell();
    194 }
    195 
    196 /*ARGSUSED*/
    197 static void clearit(Widget w, XEvent *ev, String *vector, Cardinal *count)
    198 {
    199     XCALC_PRE_OP(kCLR);
    200     clearf();
    201     post_op();
    202 }
    203 
    204 /*ARGSUSED*/
    205 static void cosine(Widget w, XEvent *ev, String *vector, Cardinal *count)
    206 {
    207     XCALC_PRE_OP(kCOS);
    208     oneop(kCOS);
    209     post_op();
    210 }
    211 
    212 /*ARGSUSED*/
    213 static void decimal(Widget w, XEvent *ev, String *vector, Cardinal *count)
    214 {
    215     XCALC_PRE_OP(kDEC);
    216     decf();
    217     post_op();
    218 }
    219 
    220 /*ARGSUSED*/
    221 static void degree(Widget w, XEvent *ev, String *vector, Cardinal *count)
    222 {
    223     XCALC_PRE_OP(kDRG);
    224     drgf();
    225     post_op();
    226 }
    227 
    228 /*ARGSUSED*/
    229 static void digit(Widget w, XEvent *ev, String *vector, Cardinal *count)
    230 {
    231     switch (vector[0][0])
    232     {
    233       case '0': XCALC_PRE_OP(kZERO); numeric(kZERO); break;
    234       case '1':	XCALC_PRE_OP(kONE); numeric(kONE); break;
    235       case '2': XCALC_PRE_OP(kTWO); numeric(kTWO); break;
    236       case '3': XCALC_PRE_OP(kTHREE); numeric(kTHREE); break;
    237       case '4': XCALC_PRE_OP(kFOUR); numeric(kFOUR); break;
    238       case '5': XCALC_PRE_OP(kFIVE); numeric(kFIVE); break;
    239       case '6': XCALC_PRE_OP(kSIX); numeric(kSIX); break;
    240       case '7': XCALC_PRE_OP(kSEVEN); numeric(kSEVEN); break;
    241       case '8': XCALC_PRE_OP(kEIGHT); numeric(kEIGHT); break;
    242       case '9': XCALC_PRE_OP(kNINE); numeric(kNINE); break;
    243       case 'A': XCALC_PRE_OP(kxA); numeric(kxA); break;
    244       case 'B': XCALC_PRE_OP(kxB); numeric(kxB); break;
    245       case 'C': XCALC_PRE_OP(kxC); numeric(kxC); break;
    246       case 'D': XCALC_PRE_OP(kxD); numeric(kxD); break;
    247       case 'E': XCALC_PRE_OP(kxE); numeric(kxE); break;
    248       case 'F': XCALC_PRE_OP(kxF); numeric(kxF); break;
    249     }
    250     post_op();
    251 }
    252 
    253 /*ARGSUSED*/
    254 static void divide(Widget w, XEvent *ev, String *vector, Cardinal *count)
    255 {
    256     XCALC_PRE_OP(kDIV);
    257     rpn  ? twof(kDIV) : twoop(kDIV);
    258     post_op();
    259 }
    260 
    261 /*ARGSUSED*/
    262 static void e(Widget w, XEvent *ev, String *vector, Cardinal *count)
    263 {
    264     XCALC_PRE_OP(kE);
    265     oneop(kE);
    266     post_op();
    267 }
    268 
    269 /*ARGSUSED*/
    270 static void enter(Widget w, XEvent *ev, String *vector, Cardinal *count)
    271 {
    272     XCALC_PRE_OP(kENTR);
    273     entrf();
    274     post_op();
    275 }
    276 
    277 /*ARGSUSED*/
    278 static void epower(Widget w, XEvent *ev, String *vector, Cardinal *count)
    279 {
    280     XCALC_PRE_OP(kEXP);
    281     oneop(kEXP);
    282     post_op();
    283 }
    284 
    285 /*ARGSUSED*/
    286 static void equal(Widget w, XEvent *ev, String *vector, Cardinal *count)
    287 {
    288     XCALC_PRE_OP(kEQU);
    289     equf();
    290     post_op();
    291 }
    292 
    293 /*ARGSUSED*/
    294 static void exchange(Widget w, XEvent *ev, String *vector, Cardinal *count)
    295 {
    296     XCALC_PRE_OP(kEXC);
    297     oneop(kEXC);
    298     post_op();
    299 }
    300 
    301 /*ARGSUSED*/
    302 static void factorial(Widget w, XEvent *ev, String *vector, Cardinal *count)
    303 {
    304     XCALC_PRE_OP(kFACT);
    305     oneop(kFACT);
    306     post_op();
    307 }
    308 
    309 /*ARGSUSED*/
    310 static void inverse(Widget w, XEvent *ev, String *vector, Cardinal *count)
    311 {
    312     XCALC_PRE_OP(kINV);
    313     invf();
    314     post_op();
    315 }
    316 
    317 /*ARGSUSED*/
    318 static void leftParen(Widget w, XEvent *ev, String *vector, Cardinal *count)
    319 {
    320     XCALC_PRE_OP(kLPAR);
    321     lparf();
    322     post_op();
    323 }
    324 
    325 /*ARGSUSED*/
    326 static void logarithm(Widget w, XEvent *ev, String *vector, Cardinal *count)
    327 {
    328     XCALC_PRE_OP(kLOG);
    329     oneop(kLOG);
    330     post_op();
    331 }
    332 
    333 /*ARGSUSED*/
    334 static void mod(Widget w, XEvent *ev, String *vector, Cardinal *count)
    335 {
    336     XCALC_PRE_OP(kMOD);
    337     rpn ? twof(kMOD) : twoop(kMOD);
    338     post_op();
    339 }
    340 
    341 /*ARGSUSED*/
    342 static void multiply(Widget w, XEvent *ev, String *vector, Cardinal *count)
    343 {
    344     XCALC_PRE_OP(kMUL);
    345     rpn ? twof(kMUL) : twoop(kMUL);
    346     post_op();
    347 }
    348 
    349 /*ARGSUSED*/
    350 static void naturalLog(Widget w, XEvent *ev, String *vector, Cardinal *count)
    351 {
    352     XCALC_PRE_OP(kLN);
    353     oneop(kLN);
    354     post_op();
    355 }
    356 
    357 /*ARGSUSED*/
    358 static void negate(Widget w, XEvent *ev, String *vector, Cardinal *count)
    359 {
    360     XCALC_PRE_OP(kNEG);
    361     negf();
    362     post_op();
    363 }
    364 
    365 /*ARGSUSED*/
    366 static void nop(Widget w, XEvent *ev, String *vector, Cardinal *count)
    367 {
    368     ringbell();
    369 }
    370 
    371 /*ARGSUSED*/
    372 static void not(Widget w, XEvent *ev, String *vector, Cardinal *count)
    373 {
    374     XCALC_PRE_OP(kNOT);
    375     oneop(kNOT);
    376     post_op();
    377 }
    378 
    379 /*ARGSUSED*/
    380 static void off(Widget w, XEvent *ev, String *vector, Cardinal *count)
    381 {
    382     XCALC_PRE_OP(kOFF);
    383     offf();
    384     post_op();
    385 }
    386 
    387 /*ARGSUSED*/
    388 static void or(Widget w, XEvent *ev, String *vector, Cardinal *count)
    389 {
    390     XCALC_PRE_OP(kOR);
    391     rpn ? twof(kOR) : twoop(kOR);
    392     post_op();
    393 }
    394 
    395 /*ARGSUSED*/
    396 static void pi(Widget w, XEvent *ev, String *vector, Cardinal *count)
    397 {
    398     XCALC_PRE_OP(kPI);
    399     oneop(kPI);
    400     post_op();
    401 }
    402 
    403 /*ARGSUSED*/
    404 static void power(Widget w, XEvent *ev, String *vector, Cardinal *count)
    405 {
    406     XCALC_PRE_OP(kPOW);
    407     rpn ? twof(kPOW) : twoop(kPOW);
    408     post_op();
    409 }
    410 
    411 /*ARGSUSED*/
    412 static void quit(Widget w, XEvent *ev, String *vector, Cardinal *count)
    413 {
    414     if (ev->type == ClientMessage &&
    415         ((Atom) ev->xclient.data.l[0]) != wm_delete_window)
    416 	ringbell();
    417     else
    418 	Quit();
    419 }
    420 
    421 /*ARGSUSED*/
    422 static void recall(Widget w, XEvent *ev, String *vector, Cardinal *count)
    423 {
    424     XCALC_PRE_OP(kRCL);
    425     rpn ? memf(kRCL) : oneop(kRCL);
    426     post_op();
    427 }
    428 
    429 /*ARGSUSED*/
    430 static void reciprocal(Widget w, XEvent *ev, String *vector, Cardinal *count)
    431 {
    432     XCALC_PRE_OP(kRECIP);
    433     oneop(kRECIP);
    434     post_op();
    435 }
    436 
    437 /*ARGSUSED*/
    438 static void rightParen(Widget w, XEvent *ev, String *vector, Cardinal *count)
    439 {
    440     XCALC_PRE_OP(kRPAR);
    441     rparf();
    442     post_op();
    443 }
    444 
    445 /*ARGSUSED*/
    446 static void roll(Widget w, XEvent *ev, String *vector, Cardinal *count)
    447 {
    448     XCALC_PRE_OP(kROLL);
    449     rollf();
    450     post_op();
    451 }
    452 
    453 /*ARGSUSED*/
    454 static void scientific(Widget w, XEvent *ev, String *vector, Cardinal *count)
    455 {
    456     XCALC_PRE_OP(kEE);
    457     eef();
    458     post_op();
    459 }
    460 
    461 /*ARGSUSED*/
    462 static void selection(Widget w, XEvent *ev, String *vector, Cardinal *count)
    463 {
    464     do_select(((XButtonReleasedEvent *)ev)->time);
    465 }
    466 
    467 /*ARGSUSED*/
    468 static void shl(Widget w, XEvent *ev, String *vector, Cardinal *count)
    469 {
    470     XCALC_PRE_OP(kSHL);
    471     rpn ? twof(kSHL) : twoop(kSHL);
    472     post_op();
    473 }
    474 
    475 /*ARGSUSED*/
    476 static void shr(Widget w, XEvent *ev, String *vector, Cardinal *count)
    477 {
    478     XCALC_PRE_OP(kSHR);
    479     rpn ? twof(kSHR) : twoop(kSHR);
    480     post_op();
    481 }
    482 
    483 /*ARGSUSED*/
    484 static void sine(Widget w, XEvent *ev, String *vector, Cardinal *count)
    485 {
    486     XCALC_PRE_OP(kSIN);
    487     oneop(kSIN);
    488     post_op();
    489 }
    490 
    491 /*ARGSUSED*/
    492 static void square(Widget w, XEvent *ev, String *vector, Cardinal *count)
    493 {
    494     XCALC_PRE_OP(kSQR);
    495     oneop(kSQR);
    496     post_op();
    497 }
    498 
    499 /*ARGSUSED*/
    500 static void squareRoot(Widget w, XEvent *ev, String *vector, Cardinal *count)
    501 {
    502     XCALC_PRE_OP(kSQRT);
    503     oneop(kSQRT);
    504     post_op();
    505 }
    506 
    507 /*ARGSUSED*/
    508 static void store(Widget w, XEvent *ev, String *vector, Cardinal *count)
    509 {
    510     XCALC_PRE_OP(kSTO);
    511     rpn ? memf(kSTO) : oneop(kSTO);
    512     post_op();
    513 }
    514 
    515 /*ARGSUSED*/
    516 static void subtract(Widget w, XEvent *ev, String *vector, Cardinal *count)
    517 {
    518     XCALC_PRE_OP(kSUB);
    519     rpn ? twof(kSUB) : twoop(kSUB);
    520     post_op();
    521 }
    522 
    523 /*ARGSUSED*/
    524 static void sum(Widget w, XEvent *ev, String *vector, Cardinal *count)
    525 {
    526     XCALC_PRE_OP(kSUM);
    527     rpn ? memf(kSUM) : oneop(kSUM);
    528     post_op();
    529 }
    530 
    531 /*ARGSUSED*/
    532 static void tangent(Widget w, XEvent *ev, String *vector, Cardinal *count)
    533 {
    534     XCALC_PRE_OP(kTAN);
    535     oneop(kTAN);
    536     post_op();
    537 }
    538 
    539 /*ARGSUSED*/
    540 static void tenpower(Widget w, XEvent *ev, String *vector, Cardinal *count)
    541 {
    542     XCALC_PRE_OP(k10X);
    543     oneop(k10X);
    544     post_op();
    545 }
    546 
    547 /*ARGSUSED*/
    548 static void xtrunc(Widget w, XEvent *ev, String *vector, Cardinal *count)
    549 {
    550     XCALC_PRE_OP(kTRUNC);
    551     oneop(kTRUNC);
    552     post_op();
    553 }
    554 
    555 /*ARGSUSED*/
    556 static void xor(Widget w, XEvent *ev, String *vector, Cardinal *count)
    557 {
    558     XCALC_PRE_OP(kXOR);
    559     rpn ? twof(kXOR) : twoop(kXOR);
    560     post_op();
    561 }
    562 
    563 /*ARGSUSED*/
    564 static void XexchangeY(Widget w, XEvent *ev, String *vector, Cardinal *count)
    565 {
    566     XCALC_PRE_OP(kXXY);
    567     twof(kXXY);
    568     post_op();
    569 }
    570