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