home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume10 / calctool24 / part02 < prev    next >
Encoding:
Text File  |  1990-01-15  |  44.0 KB  |  1,505 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v10i007: Calctool V2.4 - a simple calculator (Part 2 of 6).
  3. from: richb@Aus.Sun.COM (Rich Burridge)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 10, Issue 7
  7. Submitted-by: richb@Aus.Sun.COM (Rich Burridge)
  8. Archive-name: calctool24/part02
  9.  
  10. ---- Cut Here and unpack ----
  11. #!/bin/sh
  12. # this is part 2 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file calctool.ps continued
  15. #
  16. CurArch=2
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file calctool.ps"
  27. sed 's/^X//' << 'SHAR_EOF' >> calctool.ps
  28. X%  correct place.
  29. X
  30. X/PSMakeFrames      % wx wy width height ix iy iconic => -
  31. X{
  32. X  [ /IsIcon /IconY /IconX /KCHeight /KCWidth /KCY /KCX ]
  33. X  { exch def } forall
  34. X
  35. X%  /ScreenHeight /size framebuffer send exch def pop
  36. X  /ScreenHeight 900 def
  37. X
  38. X  /KFrame [KeyClass] [/Footer false /Label false]
  39. X    framebuffer /new OpenLookBaseFrame send def
  40. X  /KC /client KFrame send def
  41. X  KCWidth KCHeight /lockminsize KC send 
  42. X  calctoolIcon /seticon KFrame send
  43. X%  IconX
  44. X%  ScreenHeight FrameHeight sub IconY sub
  45. X%  42 64 /reshape /Icon /sendsubframe KFrame send
  46. X
  47. X  /preferredsize KFrame send /FrameHeight exch def
  48. X                             /FrameWidth  exch def
  49. X
  50. X  KCX
  51. X  ScreenHeight FrameHeight sub KCY sub
  52. X  FrameWidth FrameHeight /reshape KFrame send
  53. X
  54. X  /RFrame [RegClass] framebuffer /new OpenLookPropertyFrame send def
  55. X  /RC /client RFrame send def 
  56. X  /RCHeight 200 def
  57. X  KCWidth RCHeight /lockminsize RC send
  58. X
  59. X  /activate KFrame send
  60. X
  61. X% /map IsIcon 1 eq {/Icon /subframes KFrame send get} {KFrame} ifelse send
  62. X% IsIcon 1 eq {/close KFrame send} if
  63. X
  64. X  /map KFrame send
  65. X
  66. X  /activate RFrame send
  67. X  /place RFrame send
  68. X} def
  69. X
  70. X
  71. X%  Place a colored text string in the appropriate font at the given
  72. X%  x,y position in either the main calctool window or the memory
  73. X%  register window.
  74. X
  75. X/PSMakeText    % string x canvasheight y font color canvas => -
  76. X{
  77. X  setcanvas
  78. X  ColorTable exch get setcolor
  79. X  setfont
  80. X  sub moveto show
  81. X} def
  82. X
  83. X
  84. X/PSSetCursor   % type => -
  85. X{
  86. X} def
  87. X
  88. X
  89. X%  Depending upon the current setting, either show (map) or remove
  90. X%  (unmap) the memory register window.
  91. X
  92. X/PSToggleRegCanvas   % state => -
  93. X{
  94. X  1 eq { /map RFrame send} { /unmap RFrame send} ifelse
  95. X} def
  96. SHAR_EOF
  97. echo "File calctool.ps is complete"
  98. chmod 0444 calctool.ps || echo "restore of calctool.ps fails"
  99. set `wc -c calctool.ps`;Sum=$1
  100. if test "$Sum" != "6058"
  101. then echo original size 6058, current size $Sum;fi
  102. echo "x - extracting patchlevel.h (Text)"
  103. sed 's/^X//' << 'SHAR_EOF' > patchlevel.h &&
  104. X/*  @(#)patchlevel.h 1.12 89/12/21
  105. X *
  106. X *  This is the current patch level for this version of calctool.
  107. X *
  108. X *  Copyright (c) Rich Burridge.
  109. X *        Sun Microsystems, Australia - All rights reserved.
  110. X *
  111. X *  Permission is given to distribute these sources, as long as the
  112. X *  copyright messages are not removed, and no monies are exchanged.
  113. X *
  114. X *  No responsibility is taken for any errors or inaccuracies inherent
  115. X *  either to the comments or the code of this program, but if
  116. X *  reported to me then an attempt will be made to fix them.
  117. X */
  118. X
  119. X#define  PATCHLEVEL  4
  120. SHAR_EOF
  121. chmod 0444 patchlevel.h || echo "restore of patchlevel.h fails"
  122. set `wc -c patchlevel.h`;Sum=$1
  123. if test "$Sum" != "563"
  124. then echo original size 563, current size $Sum;fi
  125. echo "x - extracting .calctoolrc (Text)"
  126. sed 's/^X//' << 'SHAR_EOF' > .calctoolrc &&
  127. X#
  128. X#  @(#).calctoolrc 1.4 89/12/13
  129. X#
  130. X#  This is a sample .calctoolrc file. You should use this as a basis for
  131. X#  creating your own .calctoolrc files.
  132. X#
  133. X#  Process the .calctoolrc file. There are currently four types of
  134. X#  records to look for:
  135. X#
  136. X#  1) Those starting with a hash in the first column are comments.
  137. X#
  138. X#  2) Lines starting with 'c' or 'C' in the first column are
  139. X#     definitions for constants. The cC is followed by a digit in
  140. X#     the range 0-9, then a space. This is followed by a number
  141. X#     in fixed or scientific notation. Following this is an optional
  142. X#     comment, which if found, will be used in the popup menu for
  143. X#     the constants. If the comment is present, there must be at
  144. X#     least one space between this and the preceding number.
  145. X#
  146. X#  3) Those starting with a 'f' or a 'F' in the first column are
  147. X#     definitions for functions. The fF is followed by a digit in
  148. X#     the range 0-9, then a space. This is followed by a function
  149. X#     definition. Following this is an optional comment, which if
  150. X#     found, will be used in the popup menu for the functions.
  151. X#     If the comment is present, there must be at least one space
  152. X#     between this and the preceding function definition.
  153. X#
  154. X#  4) Lines starting with a 'r' or a 'R' in the first column are
  155. X#     definitions for the initial contents of the calculators
  156. X#     memory registers. The rR is followed by a digit in the
  157. X#     range 0-9, then a space. This is followed by a number in
  158. X#     fixed or scientific notation. The rest of the line is ignored.
  159. X#
  160. X#  All other lines are ignored.
  161. X#
  162. X#  Two other things to note. There should be no embedded spaces in
  163. X#  the function definitions, and whenever a backslash is found, that
  164. X#  and the following character signify a control character, for
  165. X#  example \g would be ascii 7.
  166. X#
  167. X#  CONSTANTS
  168. X#
  169. X#  This is a set of nine physical constants which could be used instead
  170. X#  of those provided by default. If you don't wish to use these, then
  171. X#  you should define your own, or comment these out.
  172. X#
  173. X
  174. Xc0 299792458          Speed of light in a vacuum (c).
  175. X
  176. Xc1 6.626176E-34       Planck's constant (h).
  177. X
  178. Xc2 6.672E-11          Gravitational constant (G).
  179. X
  180. Xc3 1.6021892E-19      Elementary charge (e).
  181. X
  182. Xc4 9.109534E-31       Electron rest mass (me).
  183. X
  184. Xc5 1.6605655E-27      Atomic mass unit (u).
  185. X
  186. Xc6 6.022045E23        Avogadro constant (Na).
  187. X
  188. Xc7 1.380662E-23       Boltzmann constant (k).
  189. X
  190. Xc8 0.02241383         Molar volume of ideal gas at s. t. p. (Vm).
  191. X
  192. X#  FUNCTIONS.
  193. X#
  194. X#  This is a sample set of functions which are assigned to the FUN key.
  195. X#
  196. X#  On a suggestion from Charles Tierney, these functions are taken from
  197. X#  the power calculation section of the March 1989 edition of the Sun
  198. X#  Configuration Guide.
  199. X#
  200. X#  f0 - Calculate AC Watts (Formula A).
  201. X#
  202. X#                            1
  203. X#      P(true) = P(DC) x  -------
  204. X#                         PS(Eff)
  205. X#
  206. X#      where P(DC) = total DC power in watts [user-calculated] - register 0.
  207. X#
  208. X#      result placed in register 1.
  209. X
  210. Xf0 r0x1.43=s1          Calculate AC Watts (Formula A).
  211. X
  212. X#  f1 - Calculate Thermal Dissipation (Formula B).
  213. X#
  214. X#                                 BTU
  215. X#     BTU(nom) = P(true) x 3.412 -----
  216. X#                                 watt
  217. X#
  218. X#     where P(true) = true AC power in watts from above - register 1.
  219. X#
  220. X#     result placed in register 2.
  221. X
  222. Xf1 r1x3.412=s2         Calculate Thermal Dissipation (Formula B).
  223. X
  224. X#  f2 - Calculate Volt - Amps (Formula C).
  225. X#
  226. X#                     1
  227. X#    VA = P(true) x ----
  228. X#                    PF
  229. X#
  230. X#    where P(true) is from the formula above  - register 1.
  231. X#
  232. X#    and PF is the Power Factor               - register 3.
  233. X#
  234. X#    Sun-3/60/140/160/180 and Sun-4/110  =  0.65
  235. X#    Sun-3/260/280 and Sun-4/260/280     =  0.715
  236. X#    Sun-3/150 and Sun-4/150             =  0.9  (at full load).
  237. X#
  238. X#    result placed in register 4.
  239. X
  240. Xf2 1/r3xr1=s4          Calculate Volt - Amps (Formula C).
  241. X
  242. X#
  243. X#   REGISTERS.
  244. X#
  245. X#   This is a sample set of initial register values. You probably
  246. X#   don't want to use these, so you should define your own or comment
  247. X#   these out.
  248. X
  249. Xr0 0.4971              Log10 of pi.
  250. X
  251. Xr1 0.4343              Log10 of e.
  252. X
  253. Xr3 57.29578            Degrees in  radian.
  254. SHAR_EOF
  255. chmod 0444 .calctoolrc || echo "restore of .calctoolrc fails"
  256. set `wc -c .calctoolrc`;Sum=$1
  257. if test "$Sum" != "4184"
  258. then echo original size 4184, current size $Sum;fi
  259. echo "x - extracting graphics.c (Text)"
  260. sed 's/^X//' << 'SHAR_EOF' > graphics.c &&
  261. X
  262. X/*  @(#)graphics.c 1.12 89/12/21
  263. X *
  264. X *  These are the independent graphics routines used by calctool.
  265. X *
  266. X *  Copyright (c) Rich Burridge.
  267. X *                Sun Microsystems, Australia - All rights reserved.
  268. X *
  269. X *  Permission is given to distribute these sources, as long as the
  270. X *  copyright messages are not removed, and no monies are exchanged.
  271. X *
  272. X *  No responsibility is taken for any errors or inaccuracies inherent
  273. X *  either to the comments or the code of this program, but if
  274. X *  reported to me then an attempt will be made to fix them.
  275. X */
  276. X
  277. X#include "calctool.h"
  278. X#include "color.h"
  279. X#include "extern.h"
  280. X
  281. X
  282. Xbut_text(row, column, portion, state)
  283. Xint row, column, portion ;
  284. Xenum but_state state ;
  285. X{
  286. X  enum font_type butfont ;
  287. X  int i, n ;
  288. X
  289. X  n = row*BCOLS*2 + column*2 + portion ;
  290. X  if (buttons[n].color == GREY) return ;
  291. X  get_label(n) ;
  292. X  for (spaces = 0, i = 0; i < strlen(pstr); i++)
  293. X    if (pstr[i] == ' ') spaces++ ;
  294. X  x = chxoff[spaces] ;
  295. X  y = (n & 1) ? 40 : 18 ;
  296. X  if (spaces == 3)  y += 4 ;
  297. X  butfont = (spaces == 3) ? BFONT : NFONT ;
  298. X  if (state == NORMAL)
  299. X    color = (!iscolor & portion) ? WHITE : BLACK ;
  300. X  if (state == INVERTED)
  301. X    color = (portion) ? BLACK : WHITE ;
  302. X  drawtext(column*(BWIDTH+BGAP)+BBORDER+x,
  303. X       DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+y, KEYCANVAS, butfont, color, pstr) ;
  304. X}
  305. X
  306. X
  307. Xdo_repaint()     /* Redraw the calctool canvas[es]. */
  308. X{
  309. X  make_canvas(0) ;
  310. X}
  311. X
  312. X
  313. Xdrawbox(x, y, width, height)
  314. Xint x, y, width, height ;
  315. X{
  316. X  drawline(x, y, x+width, y) ;
  317. X  drawline(x, y, x, y+height) ;
  318. X  drawline(x, y+height, x+width, y+height) ;
  319. X  drawline(x+width, y, x+width, y+height) ;
  320. X}
  321. X
  322. X
  323. Xdraw_button(row, column, portion, state)
  324. Xint row, column, portion ;
  325. Xenum but_state state ;
  326. X{
  327. X  int n ;
  328. X
  329. X  n = row*BCOLS*2 + column*2 + portion ;
  330. X  if (!portion)
  331. X    {
  332. X      color = (iscolor) ? buttons[n].color : WHITE ;
  333. X      drawbox(column*(BWIDTH+BGAP)+BBORDER,
  334. X              DISPLAY+row*(BHEIGHT+BGAP)+BBORDER, BWIDTH, BHEIGHT) ;
  335. X      fillbox(column*(BWIDTH+BGAP)+BBORDER+1,
  336. X              DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+1, KEYCANVAS,
  337. X              42, 50, 1, color) ;
  338. X    }
  339. X  else
  340. X    { 
  341. X      drawbox(column*(BWIDTH+BGAP)+BBORDER+5,
  342. X              DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+26, 34, 21) ;
  343. X      color = (iscolor) ? buttons[n].color : BLACK ;
  344. X      fillbox(column*(BWIDTH+BGAP)+BBORDER+6,
  345. X              DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+27, KEYCANVAS,
  346. X              32, 19, 1, color) ;
  347. X    }
  348. X  but_text(row, column, portion, state) ;
  349. X}
  350. X
  351. X
  352. Xfillbox(x, y, window, width, height, boundry, color)
  353. Xenum can_type window ;
  354. Xint x, y, width, height, boundry, color ;
  355. X{
  356. X  if (boundry)
  357. X    {
  358. X      color_area(x, y, width, height, WHITE) ;
  359. X      color_area(x+1, y+1, width-2, height-2, color) ;
  360. X    } 
  361. X  else color_area(x, y, width, height, color) ;
  362. X}
  363. X
  364. X
  365. Xget_menu_value()     /* Get menu value if valid right mouse press. */
  366. X{
  367. X  int i, n, val ;
  368. X
  369. X  n = row*BCOLS*2 + column*2 + portion ;
  370. X  for (i = 0; i < MAXMENUS; i++)
  371. X    if (buttons[n].value == validmenu[i])
  372. X      {
  373. X        val = do_menu((enum menu_type) i) ;
  374. X        if (val) handle_menu_selection(i, val) ;
  375. X        break ;
  376. X      }
  377. X}
  378. X
  379. X
  380. Xgrey_buttons(base)     /* Grey out numeric buttons depending upon base. */
  381. Xenum base_type base ;
  382. X{
  383. X  char val ;
  384. X  int column, i, n, portion, row ;
  385. X
  386. X  if (gtype == TTY) return ;
  387. X  for (i = 0; i < 16; i++)
  388. X    {
  389. X      val = digits[i] ;
  390. X      for (n = 0; n < TITEMS; n++)
  391. X        if (val == buttons[n].value) break ;           
  392. X      if (i < basevals[(int) base])          
  393. X        {                 
  394. X          if (i < 10) buttons[n].color = LBLUE ;
  395. X          else buttons[n].color = PINK ;
  396. X        }  
  397. X      else buttons[n].color = GREY ;
  398. X      row = n / (BCOLS*2) ;
  399. X      column = (n - (row*BCOLS*2)) / 2 ;
  400. X      portion = n & 1 ;
  401. X      draw_button(row, column, portion, NORMAL) ;
  402. X    }                    
  403. X}
  404. X
  405. X
  406. Xhandle_down_event(type)
  407. Xint type ;
  408. X{
  409. X  x = curx ;
  410. X  y = cury ;
  411. X  if (!down)
  412. X    {
  413. X      if (pending_op == '?')
  414. X        {
  415. X          down = type ;
  416. X          return ;
  417. X        }
  418. X      for (row = 0; row < BROWS; row++)
  419. X        for (column = 0; column < BCOLS; column++)
  420. X          if ((x > (column*(BWIDTH+BGAP)+BBORDER)) &&
  421. X              (x < (column*(BWIDTH+BGAP)+BBORDER+BWIDTH)) &&
  422. X              ((y - DISPLAY) > (row*(BHEIGHT+BGAP)+BBORDER)) &&
  423. X              ((y - DISPLAY) < (row*(BHEIGHT+BGAP)+BBORDER+BHEIGHT)))
  424. X            {
  425. X              portion = (y - DISPLAY - BBORDER -
  426. X                         (row*(BHEIGHT+BGAP))) / (BHEIGHT/2) ;
  427. X              inv_but(row, column, portion, INVERTED) ;
  428. X              down = type ;
  429. X              return ;
  430. X            }
  431. X    } 
  432. X}
  433. X
  434. X
  435. Xhandle_menu_selection(menu, item)   /* Process right button menu selection. */
  436. Xint menu, item ;
  437. X{
  438. X  pending = validmenu[menu] ;
  439. X  current = num_names[item-1][0] ;
  440. X  do_pending() ;
  441. X  down = 0 ;
  442. X  inv_but(row, column, portion, NORMAL) ;
  443. X}
  444. X
  445. X
  446. Xinv_but(row, column, portion, state)
  447. Xint row, column, portion ;
  448. Xenum but_state state ;
  449. X{
  450. X  int n ;
  451. X  n = row*BCOLS*2 + column*2 + portion ;
  452. X  if (pending_op != '?')
  453. X    {
  454. X      if (state == NORMAL)
  455. X        if (iscolor) color = buttons[n].color ;
  456. X        else color = (portion) ? BLACK : WHITE ;
  457. X      if (state == INVERTED)
  458. X        color = (portion) ? WHITE : BLACK ;
  459. X      fillbox(column*(BWIDTH+BGAP)+BBORDER+6,
  460. X              DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+5+(portion*22),
  461. X              KEYCANVAS, 32, 19, portion, color) ;
  462. X      but_text(row, column, portion, state) ;
  463. X    }
  464. X}
  465. X
  466. X
  467. Xmake_canvas(toggle)
  468. Xint toggle ;
  469. X{
  470. X  if (toggle) tstate = !tstate ;
  471. X  color = (iscolor) ? GREY : WHITE ;
  472. X  clear_canvas(KEYCANVAS, color) ;
  473. X  if (iscolor) color_area(0, 0, TWIDTH, DISPLAY, WHITE) ;
  474. X  drawline(0, DISPLAY, TWIDTH, DISPLAY) ;
  475. X  for (row = 0; row < BROWS; row++)
  476. X    for (column = 0; column < BCOLS; column++)
  477. X      for (portion = 0; portion < 2; portion++)
  478. X        draw_button(row, column, portion, NORMAL) ;
  479. X
  480. X  set_item(BASEITEM,base_str[(int) base]) ;
  481. X  set_item(DISPLAYITEM, display) ;
  482. X  set_item(NUMITEM, dtype_str[(int) dtype]) ;
  483. X  set_item(OPITEM, items[(int) OPITEM].text) ;
  484. X  set_item(TTYPEITEM,ttype_str[(int) ttype]) ;
  485. X  set_item(HYPITEM, (hyperbolic) ? "HYP " : "    ") ;
  486. X  set_item(INVITEM, (inverse) ? "INV " : "    ") ;
  487. X  make_registers() ;
  488. X}
  489. X
  490. X
  491. Xmake_menus()      /* Create the popup menus used by the graphics versions. */
  492. X{
  493. X
  494. X/*  There are nine popup menus. These are associated with the following keys:
  495. X *
  496. X *  ACC  - range of possible accuracies (0 - 9).
  497. X *
  498. X *  CON  - constant values plus associated comments, if present.
  499. X *
  500. X *  EXCH - list of register numbers (0 - 9).
  501. X *
  502. X *  FUN  - function definitions plus associated comments, if present.
  503. X *
  504. X *  HELP - contains all the keys in the calculator.
  505. X *
  506. X *   <   - range of possible left shift values (0 - 9).
  507. X *
  508. X *   >   - range of possible right shift values (0 - 9).
  509. X *
  510. X *  RCL  - list of register numbers (0 - 9).
  511. X *
  512. X *  STO  - list of register numbers (0 - 9).
  513. X */
  514. X
  515. X  create_menu(M_ACC) ;     /* Accuracies. */
  516. X  create_menu(M_CON) ;     /* Constant definitions. */
  517. X  create_menu(M_EXCH) ;    /* Register exchange. */
  518. X  create_menu(M_FUN) ;     /* Function definitions. */
  519. X  create_menu(M_LSHIFT) ;  /* Left shift. */
  520. X  create_menu(M_RSHIFT) ;  /* Right shift. */
  521. X  create_menu(M_RCL) ;     /* Register recall. */
  522. X  create_menu(M_STO) ;     /* Register store. */
  523. X}
  524. X
  525. X
  526. Xmake_registers()           /* Calculate memory register frame values. */
  527. X{
  528. X  char line[MAXLINE] ;     /* Current memory register line. */
  529. X  int n ;
  530. X
  531. X  if (!rstate) return ;
  532. X  clear_canvas(REGCANVAS, WHITE) ;
  533. X  drawtext(15, 20, REGCANVAS, NFONT, BLACK, "Memory Registers") ;
  534. X  for (n = 0; n < MAXREGS; n++)
  535. X    {
  536. X      SPRINTF(line, "%1d   %s", n, make_number(mem_vals[n])) ;
  537. X      drawtext(15, 40+15*n, REGCANVAS, NFONT, BLACK, line) ;
  538. X    }
  539. X}
  540. X
  541. X
  542. Xprocess_event(type)       /* Process this event. */
  543. Xint type ;
  544. X{
  545. X  int i, n ;
  546. X
  547. X  n = row*BCOLS*2 + column*2 + portion ;
  548. X  switch (type)
  549. X    {
  550. X      case CFRAME_REPAINT  : make_canvas(0) ;
  551. X                             set_item(BASEITEM, base_str[(int) base]) ;
  552. X                             set_item(TTYPEITEM, ttype_str[(int) ttype]) ;
  553. X                             break ;
  554. X      case EXIT_WINDOW     : if (pending_op != '?')
  555. X                               if (n >= 0 && n <= (NOBUTTONS*2))
  556. X                                 {
  557. X                                   draw_button(row, column, portion, NORMAL) ;
  558. X                                   if (!portion)
  559. X                                     draw_button(row, column, 1, NORMAL) ;
  560. X                                 }
  561. X                             down = 0 ;
  562. X                             break ;
  563. X      case KEYBOARD        : nextc = cur_ch ;
  564. X                             for (n = 0; n < TITEMS; n++)
  565. X                               if (nextc == buttons[n].value) break ;
  566. X                             if (n == TITEMS) return ;
  567. X                             if (n >= 0 && n <= TITEMS)
  568. X                               process_item(n) ;
  569. X                             break ;
  570. X      case LEFT_DOWN       :
  571. X      case MIDDLE_DOWN     :
  572. X      case RIGHT_DOWN      : handle_down_event(type) ;
  573. X                             if (type == RIGHT_DOWN) get_menu_value() ;
  574. X                             break ;
  575. X      case LEFT_UP         :
  576. X      case MIDDLE_UP       :
  577. X      case RIGHT_UP        : x = curx ;
  578. X                             y = cury ;
  579. X                             if ((type == LEFT_UP && down == LEFT_DOWN) ||
  580. X                                 (type == MIDDLE_UP && down == MIDDLE_DOWN) ||
  581. X                                 (type == RIGHT_UP && down == RIGHT_DOWN))
  582. X                               {
  583. X                                 if (pending_op != '?' && n <= (NOBUTTONS*2))
  584. X                                   inv_but(row, column, portion, NORMAL) ;
  585. X                                 down = 0 ;
  586. X                                 if (n >= 0 && n <= (NOBUTTONS*2))
  587. X                                   process_item(n) ;
  588. X                               }
  589. X                             break ;
  590. X      case RFRAME_REPAINT  : make_registers() ;
  591. X                             break ;
  592. X      case TAKE_FROM_SHELF : handle_selection() ;
  593. X                             if (issel)
  594. X                               for (i = 0 ; i < strlen(selection); i++)
  595. X                                 for (n = 0; n < TITEMS; n++)
  596. X                                   if (selection[i] == buttons[n].value)
  597. X                                     {
  598. X                                       process_item(n) ;
  599. X                                       break ;
  600. X                                     }
  601. X                             break ;
  602. X      case PUT_ON_SHELF    : get_display() ;
  603. X                             break ;
  604. X      case DIED            : exit(0) ;
  605. X    }                           
  606. X}
  607. X
  608. X
  609. Xset_item(itemno, str)
  610. Xenum item_type itemno ;
  611. Xchar *str ;
  612. X{
  613. X  enum font_type font ;
  614. X  char *old_text ;
  615. X  int x, y ;
  616. X  old_text = items[(int) itemno].text ;
  617. X  if (itemno == DISPLAYITEM)
  618. X    x = 5+(MAX_DIGITS - strlen(old_text))*nfont_width ;
  619. X  else x = items[(int) itemno].x ;
  620. X  y = items[(int) itemno].y ;
  621. X  font = items[(int) itemno].font ;
  622. X  old_text = items[(int) itemno].text ;
  623. X  drawtext(x, y, KEYCANVAS, font, WHITE, old_text) ;
  624. X
  625. X  if (itemno == DISPLAYITEM) x = 5+(MAX_DIGITS - strlen(str))*nfont_width ;
  626. X
  627. X  drawtext(x, y, KEYCANVAS, font, BLACK, str) ;
  628. X  STRCPY(items[(int) itemno].text, str) ;
  629. X}
  630. SHAR_EOF
  631. chmod 0444 graphics.c || echo "restore of graphics.c fails"
  632. set `wc -c graphics.c`;Sum=$1
  633. if test "$Sum" != "11290"
  634. then echo original size 11290, current size $Sum;fi
  635. echo "x - extracting display.c (Text)"
  636. sed 's/^X//' << 'SHAR_EOF' > display.c &&
  637. X
  638. X/*  @(#)display.c 1.8 89/11/01
  639. X *
  640. X *  Display manipulation routines used by calctool.
  641. X *
  642. X *  Copyright (c) Rich Burridge.
  643. X *                Sun Microsystems, Australia - All rights reserved.
  644. X *
  645. X *  Basic algorithms, copyright (c) Ed Falk.
  646. X *                Sun Microsystems, Mountain View.
  647. X *
  648. X *  Permission is given to distribute these sources, as long as the
  649. X *  copyright messages are not removed, and no monies are exchanged.
  650. X *
  651. X *  No responsibility is taken for any errors or inaccuracies inherent
  652. X *  either to the comments or the code of this program, but if
  653. X *  reported to me then an attempt will be made to fix them.
  654. X */
  655. X
  656. X#include "calctool.h"
  657. X#include "color.h"
  658. X#include "extern.h"
  659. X
  660. X
  661. Xchar_val(chr)
  662. Xchar chr ;
  663. X{
  664. X       if (chr >= '0' && chr <= '9') return(chr - '0') ;
  665. X  else if (chr >= 'a' && chr <= 'f') return(chr - 'a' + 10) ;
  666. X  else return(-1) ;
  667. X}
  668. X
  669. X
  670. Xclear_display()
  671. X{
  672. X  int i ;
  673. X
  674. X  pointed = 0 ;
  675. X  toclear = 1 ;
  676. X  STRCPY(display, "0.") ;
  677. X  for (i = 0; i < accuracy; i++) STRNCAT(display, "0", 1) ;
  678. X  set_item(DISPLAYITEM, display) ;
  679. X  hyperbolic = inverse = 0 ;
  680. X  set_item(HYPITEM, "    ") ;
  681. X  set_item(INVITEM, "    ") ;
  682. X  disp_val = 0.0 ;
  683. X}
  684. X
  685. X
  686. Xdouble
  687. Xconvert_display()    /* Convert input string into a double. */
  688. X{
  689. X  int exp, exp_sign, i, inum ;
  690. X  double val ;
  691. X  char *optr ;
  692. X
  693. X  val = 0.0 ;
  694. X  exp = 0 ;
  695. X  optr = display ;
  696. X  while ((inum = char_val(*optr)) >= 0)
  697. X    {
  698. X      val = val * basevals[(int) base] + inum ;
  699. X      *optr++ ;
  700. X    }
  701. X      
  702. X  if (*optr == '.')
  703. X    for (i = 1; (inum = char_val(*++optr)) >= 0; i++)
  704. X      val += inum / powers[i][(int) base] ;
  705. X
  706. X  while (*optr == ' ') optr++ ;
  707. X
  708. X  if (*optr != '\0')
  709. X    {
  710. X      if (*optr == '-') exp_sign = -1 ;
  711. X      else exp_sign = 1 ;
  712. X
  713. X      while ((inum = char_val(*++optr)) >= 0)
  714. X        exp = exp * basevals[(int) base] + inum ;
  715. X    }
  716. X  exp *= exp_sign ;
  717. X
  718. X  if (key_exp)
  719. X    val *= pow((double) basevals[(int) base], (double) exp) ;
  720. X  return(val) ;
  721. X}
  722. Xget_label(n)
  723. Xint n ;
  724. X{
  725. X  if (tstate)
  726. X    switch (buttons[n].value)
  727. X        {
  728. X          case CCTRL('c') :
  729. X          case CCTRL('d') :
  730. X          case CCTRL('e') :
  731. X          case CCTRL('f') :
  732. X          case CCTRL('g') :
  733. X          case CCTRL('n') :
  734. X          case CCTRL('r') :
  735. X          case CCTRL('s') :
  736. X          case CCTRL('t') : SPRINTF(pstr, "^%c  ", buttons[n].value + 96) ;
  737. X                            break ;
  738. X          case CCTRL('h') : STRCPY(pstr, "bsp ") ;
  739. X                            break ;
  740. X          case '\177'     : STRCPY(pstr, "del ") ;
  741. X                            break ;
  742. X          default         : SPRINTF(pstr, "%c   ", buttons[n].value) ;
  743. X        }
  744. X  else STRCPY(pstr, buttons[n].str) ;
  745. X}
  746. X
  747. X
  748. Xinitialise()
  749. X{
  750. X  error = 0 ;              /* Currently no display error. */
  751. X  cur_op = '?' ;           /* No arithmetic operator defined yet. */
  752. X  old_cal_value = '?' ;
  753. X  result = 0.0 ;           /* No previous result yet. */
  754. X  last_input = 0.0 ;
  755. X}
  756. X
  757. X
  758. Xchar *
  759. Xmake_fixed(number, cmax)    /* Convert fixed number. */
  760. Xdouble number ;             /* Value to convert. */
  761. Xint cmax ;                  /* Maximum characters to generate. */
  762. X{
  763. X  char *optr ;
  764. X  double val ;
  765. X  int ndig ;                   /* Total number of digits to generate. */
  766. X  int ddig ;                   /* Number of digits to left of . */
  767. X  int dval ;
  768. X
  769. X  optr = fnum ;
  770. X  val = fabs(number) ;
  771. X  if (number < 0.0) *optr++ = '-' ;
  772. X  val += .5 / powers[accuracy][(int) base] ;
  773. X
  774. X  if (val < 1.0)
  775. X    {
  776. X      ddig = 0 ;
  777. X      *optr++ = '0' ;
  778. X      cmax-- ;
  779. X    }
  780. X  else
  781. X    {
  782. X      for (ddig = 0; val >= 1.0; ddig++)
  783. X        val /= powers[1][(int) base] ;
  784. X    }
  785. X
  786. X  ndig = MIN(ddig + accuracy, --cmax) ;
  787. X
  788. X  while (ndig-- > 0)
  789. X    {
  790. X      if (ddig-- == 0) *optr++ = '.' ;
  791. X      val *= powers[1][(int) base] ;
  792. X      dval = val ;
  793. X      *optr++ = digits[dval] ;
  794. X      val -= (int) val ;
  795. X    }
  796. X  *optr++ = '\0' ;
  797. X  toclear = 1 ;
  798. X  pointed = 0 ;
  799. X  return(fnum) ;
  800. X}
  801. X
  802. X
  803. Xchar *
  804. Xmake_number(number)     /* Convert display value to current base. */
  805. Xdouble number ;         /* Value to convert. */
  806. X{
  807. X  double val ;
  808. X
  809. X  if (isinf(number) || isnan(number))
  810. X    {
  811. X      STRCPY(display, "Error") ;
  812. X      error = 1 ;
  813. X      set_item(OPITEM, "CLR") ;
  814. X      return(display) ;
  815. X    }
  816. X
  817. X  val = fabs(number) ;
  818. X  if (dtype == SCI ||
  819. X      dtype == FIX && val != 0.0 && (val > max_fix[(int) base] ||
  820. X                      val < exp_p1[accuracy][(int) base]))
  821. X    return(make_scientific(number)) ;
  822. X  else return(make_fixed(number, MAX_DIGITS)) ;
  823. X}
  824. X
  825. X
  826. Xchar *
  827. Xmake_scientific(number)     /* Convert scientific number. */
  828. Xdouble number ;             /* Value to convert. */
  829. X{
  830. X  char fixed[MAX_DIGITS+1] ;
  831. X  char *optr ;
  832. X  double mant ;                /* Mantissa */
  833. X  double val ;
  834. X  int exp = 0 ;                /* Exponent */
  835. X  int i ;
  836. X  int eng = 0 ;                /* Scientific not engineering value. */
  837. X  double atmp ;
  838. X
  839. X  optr = snum ;
  840. X  val = fabs(number) ;
  841. X  if (number < 0.0) *optr++ = '-' ;
  842. X  mant = val ;
  843. X  atmp = 1.0 / powers[10][(int) base] ;
  844. X
  845. X  if (mant != 0.0)
  846. X    {
  847. X      while (mant >= powers[10][(int) base])
  848. X        {
  849. X          exp += 10 ;
  850. X          mant *= atmp ;
  851. X        }
  852. X        
  853. X      while ((!eng && mant >= powers[1][(int) base]) ||
  854. X             (eng && (mant >= powers[3][(int) base] || exp % 3 != 0)))
  855. X        {
  856. X          exp += 1 ;
  857. X          mant /= powers[1][(int) base] ;
  858. X        }
  859. X      while (mant < atmp)
  860. X        {
  861. X          exp -= 10 ;
  862. X          mant *= powers[10][(int) base] ;
  863. X        }
  864. X
  865. X      while (mant < 1.0 || (eng && exp % 3 != 0))
  866. X        {
  867. X          exp -= 1 ;
  868. X          mant *= powers[1][(int) base] ;
  869. X        }
  870. X    }    
  871. X
  872. X  STRCPY(fixed, make_fixed(mant, MAX_DIGITS-6)) ;
  873. X  for (i = 0; i < strlen(fixed); i++) *optr++ = fixed[i] ;
  874. X
  875. X  *optr++ = 'e' ;
  876. X
  877. X  if (exp < 0)
  878. X    {
  879. X      exp = -exp ;
  880. X      *optr++ = '-' ;
  881. X    }
  882. X  else *optr++ = '+' ;
  883. X
  884. X  if ((*optr = digits[exp / ((int) powers[2][(int) base])]) != '0')
  885. X    optr++  ;
  886. X  exp %= (int) powers[2][(int) base] ;
  887. X  *optr++ = digits[exp / ((int) powers[1][(int) base])] ;
  888. X  exp %= (int) powers[1][(int) base] ;
  889. X  *optr++ = digits[exp] ;
  890. X  *optr++ = '\0' ;
  891. X  toclear = 1 ;
  892. X  pointed = 0 ;
  893. X  return(snum) ;
  894. X}
  895. X
  896. X
  897. Xprocess_item(n)
  898. Xint n ;
  899. X{
  900. X  int i,isvalid ;
  901. X
  902. X  if (n < 0 || n > TITEMS) return ;
  903. X
  904. X  current = buttons[n].value ;
  905. X  if (current == 'X') current = 'x' ;         /* Reassign "extra" values. */
  906. X  if (current == '*') current = 'x' ;
  907. X  if (current == '\015') current = '=' ;
  908. X  if (current == 'Q') current = 'q' ;
  909. X
  910. X  if (error)
  911. X    {
  912. X      isvalid = 0 ;                    /* Must press a valid key first. */
  913. X      for (i = 0; i < MAXVKEYS; i++)
  914. X        if (current == validkeys[i]) isvalid = 1 ;
  915. X      if (pending == '?') isvalid = 1 ;
  916. X      if (!isvalid) return ;
  917. X      error = 0 ;
  918. X    }
  919. X
  920. X  if (pending)
  921. X    {
  922. X      for (n = 0; n < TITEMS; n++)
  923. X        if (pending == buttons[n].value) break ;
  924. X    }
  925. X  switch (buttons[n].opdisp)
  926. X    {
  927. X      case OP_SET   : set_item(OPITEM, buttons[n].str) ;
  928. X                            break ;
  929. X      case OP_CLEAR : if (error) set_item(OPITEM, "CLR") ;
  930. X                            else set_item(OPITEM, "") ;
  931. X    }
  932. X  (*buttons[n].func)() ;
  933. X}
  934. X
  935. X
  936. Xshow_display(val)
  937. Xdouble val ;
  938. X{
  939. X  if (!error)
  940. X    {
  941. X      STRCPY(display, make_number(val)) ;
  942. X      set_item(DISPLAYITEM, display) ;
  943. X    }
  944. X}
  945. SHAR_EOF
  946. chmod 0444 display.c || echo "restore of display.c fails"
  947. set `wc -c display.c`;Sum=$1
  948. if test "$Sum" != "7188"
  949. then echo original size 7188, current size $Sum;fi
  950. echo "x - extracting functions.c (Text)"
  951. sed 's/^X//' << 'SHAR_EOF' > functions.c &&
  952. X
  953. X/*  @(#)functions.c 1.7 89/11/01
  954. X *
  955. X *  This file contains the seperate functions used by calctool,
  956. X *  whenever a calculator button is pressed.
  957. X *
  958. X *  Copyright (c) Rich Burridge.
  959. X *                Sun Microsystems, Australia - All rights reserved.
  960. X *
  961. X *  Basic algorithms, copyright (c) Ed Falk.
  962. X *                Sun Microsystems, Mountain View.
  963. X *
  964. X *  Permission is given to distribute these sources, as long as the
  965. X *  copyright messages are not removed, and no monies are exchanged.
  966. X *
  967. X *  No responsibility is taken for any errors or inaccuracies inherent
  968. X *  either to the comments or the code of this program, but if
  969. X *  reported to me then an attempt will be made to fix them.
  970. X */
  971. X
  972. X#include "calctool.h"
  973. X#include "color.h"
  974. X#include "extern.h"
  975. X
  976. XBOOLEAN ibool() ;
  977. Xdouble setbool() ;
  978. X
  979. X
  980. Xdo_accuracy()     /* Set display accuracy. */
  981. X{
  982. X  if (current >= '0' && current <= '9')
  983. X    {
  984. X      accuracy = char_val(current) ;
  985. X      make_registers() ;
  986. X    }
  987. X}
  988. X
  989. X
  990. Xdo_base()    /* Change the current base setting. */
  991. X{
  992. X  switch (current)
  993. X    {
  994. X      case 'B' : base = BIN ;
  995. X                 break ;
  996. X      case 'O' : base = OCT ;
  997. X                 break ;
  998. X      case 'D' : base = DEC ;
  999. X                 break ;
  1000. X      case 'H' : base = HEX ;
  1001. X    }
  1002. X  grey_buttons(base) ;
  1003. X  set_item(BASEITEM, base_str[(int) base]) ;
  1004. X  show_display(disp_val) ;
  1005. X  if (rstate) make_registers() ;
  1006. X}
  1007. X
  1008. X
  1009. Xdo_calculation()      /* Perform arithmetic calculation and display result. */
  1010. X{
  1011. X  if (current == '=' && old_cal_value == '=')
  1012. X    if (new_input) result = last_input ;
  1013. X    else disp_val = last_input ;
  1014. X
  1015. X  if (current != '=' && old_cal_value == '=') cur_op = '?' ;
  1016. X  switch (cur_op)
  1017. X    {
  1018. X      case CCTRL('c') :                              /* cos. */
  1019. X      case CCTRL('s') :                              /* sin. */
  1020. X      case CCTRL('t') :                              /* tan. */
  1021. X      case '?'        : result = disp_val ;          /* Undefined. */
  1022. X                        break ;
  1023. X      case '+'        : result += disp_val ;         /* Addition. */
  1024. X                        break ;
  1025. X      case '-'        : result -= disp_val ;         /* Subtraction. */
  1026. X                        break ;
  1027. X      case 'x'        : result *= disp_val ;         /* Multiplication. */
  1028. X                        break ;
  1029. X      case '/'        : result /= disp_val ;         /* Division. */
  1030. X                        break ;
  1031. X      case '%'        : result *= disp_val * 0.01 ;              /* % */
  1032. X                        break ;
  1033. X      case 'Y'        : result = pow(result, disp_val) ;         /* y^x */
  1034. X                        break ;
  1035. X      case '&'        : result = setbool(ibool(result) &         /* AND */
  1036. X                                         ibool(disp_val)) ;
  1037. X                        break ;
  1038. X      case '|'        : result = setbool(ibool(result) |         /* OR */
  1039. X                                         ibool(disp_val)) ;
  1040. X                        break ;
  1041. X      case '^'        : result = setbool(ibool(result) ^         /* XOR */
  1042. X                                         ibool(disp_val)) ;
  1043. X                        break ;
  1044. X      case 'n'        : result = setbool(~(ibool(result) ^       /* XNOR */
  1045. X                                           ibool(disp_val))) ;
  1046. X                        break ;
  1047. X      case '='        : break ;                                  /* Equals. */
  1048. X    }
  1049. X  show_display(result) ;
  1050. X  if (!(current == '=' && old_cal_value == '=')) last_input = disp_val ;
  1051. X
  1052. X  disp_val = result ;
  1053. X  if (current != '=') cur_op = current ;
  1054. X  old_cal_value = current ;
  1055. X  new_input = key_exp = 0 ;
  1056. X}
  1057. X
  1058. X
  1059. Xdo_clear()       /* Clear the calculator display and re-initialise. */
  1060. X{
  1061. X  clear_display() ;
  1062. X  if (error) set_item(DISPLAYITEM, "") ;
  1063. X  initialise() ;
  1064. X}
  1065. X
  1066. X
  1067. Xdo_constant()
  1068. X{
  1069. X  if (current >= '0' && current <= '9')
  1070. X    {
  1071. X      disp_val = con_vals[char_val(current)] ;
  1072. X      show_display(disp_val) ;
  1073. X    }
  1074. X}
  1075. X
  1076. X
  1077. Xdo_delete()     /* Remove the last numeric character typed. */
  1078. X{
  1079. X  if (strlen(display)) display[strlen(display)-1] = '\0' ;
  1080. X
  1081. X/*  If we were entering a scientific number, and we have backspaced over
  1082. X *  the exponent sign, then this reverts to entering a fixed point number.
  1083. X */
  1084. X
  1085. X  if (key_exp && !(index(display, '+')))
  1086. X    {
  1087. X      key_exp = 0 ;
  1088. X      display[strlen(display)-1] = '\0' ;
  1089. X      set_item(OPITEM, "") ;
  1090. X    }
  1091. X
  1092. X  set_item(DISPLAYITEM, display) ;
  1093. X  disp_val = convert_display() ;    /* Convert input to a number. */
  1094. X}
  1095. X
  1096. X
  1097. Xdo_exchange()         /* Exchange display with memory register. */
  1098. X{
  1099. X  double temp ;
  1100. X
  1101. X  if (current >= '0' && current <= '9')
  1102. X    {
  1103. X      temp = disp_val ;
  1104. X      disp_val = mem_vals[char_val(current)] ;
  1105. X      mem_vals[char_val(current)] = temp ;
  1106. X      make_registers() ;
  1107. X    }
  1108. X}
  1109. X
  1110. X
  1111. Xdo_expno()           /* Get exponential number. */
  1112. X{
  1113. X  if (!new_input)
  1114. X    {
  1115. X      STRCPY(display, "1.0 +") ;
  1116. X      new_input = pointed = 1 ;
  1117. X    }
  1118. X  else if (!pointed)
  1119. X    {
  1120. X      STRNCAT(display, ". +", 3) ;
  1121. X      pointed = 1 ;
  1122. X    }
  1123. X  else STRNCAT(display, " +", 2) ;
  1124. X  key_exp = 1 ;
  1125. X  exp_posn = index(display, '+') ;
  1126. X  set_item(DISPLAYITEM, display) ;
  1127. X  disp_val = convert_display() ;       /* Convert input to a number. */
  1128. X}
  1129. X
  1130. X
  1131. Xdouble
  1132. Xdo_factorial(val)     /* Calculate the factorial of val. */
  1133. Xdouble val ;
  1134. X{
  1135. X  double a ;
  1136. X  int i ;
  1137. X
  1138. X  if (val == (int) val)
  1139. X    {
  1140. X      i = val ;
  1141. X      a = 1.0 ;
  1142. X      while ((i > 0) && (a != HUGE)) a *= (float) i-- ;
  1143. X    }
  1144. X  else
  1145. X    {
  1146. X      a = gamma(val+1) ;
  1147. X      a = exp(a) ;
  1148. X      if (signgam) a = -a ;
  1149. X    }
  1150. X  return (a) ;
  1151. X}
  1152. X
  1153. X
  1154. Xdo_function()      /* Perform a user defined function. */
  1155. X{
  1156. X  int fno, i, n ;
  1157. X
  1158. X  pending = 0 ;
  1159. X  if (current >= '0' && current <= '9')
  1160. X    {
  1161. X      fno = char_val(current) ;
  1162. X      for (i = 0 ; i < strlen(fun_vals[fno]); i++)
  1163. X        for (n = 0; n < TITEMS; n++)
  1164. X          if (fun_vals[fno][i] == buttons[n].value)
  1165. X            {
  1166. X              process_item(n) ;
  1167. X              break ;
  1168. X            }
  1169. X    }
  1170. X}
  1171. X
  1172. X
  1173. Xdo_help()         /* Show online help facility. */
  1174. X{
  1175. X  char help_str[MAXLINE], nextline[MAXLINE], *p ;
  1176. X  int n, y ;
  1177. X
  1178. X  if (pending_op == '?')                        /* HELP. */
  1179. X    {     
  1180. X      if (ishelp) ishelp++ ;
  1181. X      pending_op = '=' ;
  1182. X      make_canvas(0) ;
  1183. X      set_cursor(MAINCURSOR) ;
  1184. X    }     
  1185. X  else    
  1186. X    {
  1187. X      clear_canvas(KEYCANVAS, WHITE) ;
  1188. X      y = 20 ;
  1189. X      if (!ishelp)
  1190. X        drawtext(5, y, KEYCANVAS, NFONT, BLACK, "No help file found.") ;
  1191. X      else
  1192. X        {
  1193. X          for (n = 0; n < TITEMS; n++)
  1194. X            if (current == buttons[n].value) break ;
  1195. X          color = (iscolor) ? buttons[n].color : WHITE ;
  1196. X          clear_canvas(KEYCANVAS, color) ;
  1197. X          SPRINTF(help_str, "_%s_\n", buttons[n].str) ;
  1198. X          rewind(hfd) ;
  1199. X          y = 15 ;
  1200. X          p = fgets(nextline, BUFSIZ, hfd) ;
  1201. X          if (EQUAL(p, "_calctool.help_\n"))
  1202. X            {
  1203. X              while (p = fgets(nextline, BUFSIZ, hfd))
  1204. X                if (*p == '_' && EQUAL(p, help_str)) break ;
  1205. X              if (!p) drawtext(5, y, KEYCANVAS, NFONT, BLACK,
  1206. X                               "No help for this item.") ;
  1207. X              for (;;)
  1208. X                {
  1209. X                  FGETS(nextline, BUFSIZ, hfd) ;
  1210. X                  if (nextline[0] == '_') break ;
  1211. X                  nextline[strlen(nextline)-1] = '\0' ;
  1212. X                  drawtext(5, y, KEYCANVAS, NFONT, BLACK, nextline) ;
  1213. X                  y += 15 ;
  1214. X                }
  1215. X            }    
  1216. X          else drawtext(5, y, KEYCANVAS, NFONT, BLACK,
  1217. X                        "Invalid help file given.") ;
  1218. X        }
  1219. X      drawtext(5, y+25, KEYCANVAS, NFONT, BLACK,
  1220. X               "Click LEFT or press any valid key.") ;
  1221. X      pending_op = '?' ;
  1222. X      return ;
  1223. X    }
  1224. X}
  1225. X
  1226. X
  1227. Xdo_immediate()
  1228. X{
  1229. X  switch (current)
  1230. X    {
  1231. X      case '[' : disp_val = setbool(ibool(disp_val)) ;          /* &32 */
  1232. X                 break ;
  1233. X      case ']' : disp_val = setbool(ibool(disp_val) & 0xffff) ; /* &16 */
  1234. X                 break ;
  1235. X      case '{' : disp_val = exp(disp_val) ;                     /* e^x */
  1236. X                 break ;
  1237. X      case '}' : disp_val = exp(M_LN10*disp_val) ;              /* 10^x */
  1238. X                 break ;
  1239. X      case 'N' : disp_val = log(disp_val) ;                     /* ln */
  1240. X                 break ;
  1241. X      case 'G' : disp_val = log10(disp_val) ;                   /* log */
  1242. X                 break ;
  1243. X      case 'S' : disp_val = sqrt(disp_val) ;                    /* SQRT */
  1244. X                 break ;
  1245. X      case '~' : disp_val = setbool(~ibool(disp_val)) ;         /* NOT */
  1246. X                 break ;
  1247. X      case 'R' : disp_val = 1.0 / disp_val ;                    /* 1/x */
  1248. X                 break ;
  1249. X      case '!' : disp_val = do_factorial(disp_val) ;            /* x! */
  1250. X                 break ;
  1251. X      case '@' : disp_val *= disp_val ;                         /* x^2 */
  1252. X                 break ;
  1253. X      case 'C' : if (key_exp)                                   /* CHS */
  1254. X                   {
  1255. X                     if (*exp_posn == '+') *exp_posn = '-' ;
  1256. X                     else                  *exp_posn = '+' ;
  1257. X                     set_item(DISPLAYITEM, display) ;
  1258. X                     disp_val = convert_display() ;
  1259. X                     key_exp = 0 ;
  1260. X                   }
  1261. X                 else disp_val = -disp_val ;
  1262. X    }
  1263. X  show_display(disp_val) ;
  1264. X}
  1265. X
  1266. X
  1267. Xdo_keys()      /* Display/undisplay the calctool key values. */
  1268. X{
  1269. X  make_canvas(1) ;
  1270. X}
  1271. X
  1272. X
  1273. Xdo_number()
  1274. X{
  1275. X  int n ;
  1276. X  static int maxvals[4] = {1, 7, 9, 15} ;
  1277. X
  1278. X  n = current - '0' ;
  1279. X  if (base == HEX && current >= 'a' && current <= 'f')
  1280. X    n = current - 'a' + 10 ;
  1281. X  if (n > maxvals[(int) base]) return ;
  1282. X
  1283. X  if (toclear)
  1284. X    {
  1285. X      SPRINTF(display, "%c", current) ;
  1286. X      toclear = 0 ;
  1287. X    }
  1288. X  else if (strlen(display) < disp_length[(int) base])
  1289. X    STRNCAT(display, ¤t, 1) ;
  1290. X  set_item(DISPLAYITEM, display) ;
  1291. X  disp_val = convert_display() ;    /* Convert input to a number. */
  1292. X  new_input = 1 ;
  1293. X}
  1294. X
  1295. X
  1296. Xdo_numtype()         /* Set number type (fixed or scientific). */
  1297. X{
  1298. X  int n ;
  1299. X
  1300. X  if (dtype == FIX) dtype = SCI ;
  1301. X  else dtype = FIX ;
  1302. X  n = row*BCOLS*2 + column*2 + portion ;
  1303. X  STRCPY(buttons[n].str, (dtype == FIX) ? "SCI " : "FIX ") ;
  1304. X  set_item(NUMITEM, dtype_str[(int) dtype]) ;
  1305. X  draw_button(row, column, 0, NORMAL) ;
  1306. X  draw_button(row, column, 1, NORMAL) ;
  1307. X  show_display(disp_val) ;
  1308. X}
  1309. X
  1310. X
  1311. Xdo_pending()
  1312. X{
  1313. X  grey_buttons(HEX) ;    /* Reshow all the keys. */
  1314. X  switch (pending)
  1315. X    {
  1316. X      case '#'        : do_constant() ;                            /* CON */
  1317. X                        break ;
  1318. X      case CCTRL('e') : do_exchange() ;                            /* EXCH */
  1319. X                        break ;
  1320. X      case CCTRL('f') : do_function() ;                            /* FUN */
  1321. X                        break ;
  1322. X      case 's'        :                                            /* STO */
  1323. X      case 'r'        : do_sto_rcl() ;                             /* RCL */
  1324. X                        if (pending_op == '+' || pending_op == '-' ||
  1325. X                            pending_op == 'x' || pending_op == '/') return ;
  1326. X                        break ;
  1327. X      case '<'        :                                            /* < */
  1328. X      case '>'        : do_shift() ;                               /* > */
  1329. X                        break ;
  1330. X      case 'A'        : do_accuracy() ;                            /* ACC */
  1331. X                        break ;
  1332. X      case '?'        : do_help() ;                                /* ? */
  1333. X                        if (pending_op == '?') return ;
  1334. X                        break ;
  1335. X      default         : if (!pending)
  1336. X                          {
  1337. X                            pending = current ;
  1338. X                            pending_op = '=' ;
  1339. X                            if (pending == '?') set_cursor(HELPCURSOR) ;
  1340. X                            if (pending == '?' && (ishelp <= 1)) do_pending() ;
  1341. X                            return ;
  1342. X                          }
  1343. X    }
  1344. X  show_display(disp_val) ;
  1345. X  if (error) set_item(OPITEM, "CLR") ;
  1346. X  else set_item(OPITEM, "") ;
  1347. X  pending = 0 ;
  1348. X  grey_buttons(base) ;      /* Just show numeric keys for current base. */
  1349. X}
  1350. X
  1351. X
  1352. Xdo_point()                  /* Handle numeric point. */
  1353. X{
  1354. X  if (!pointed)
  1355. X    {
  1356. X      if (toclear)
  1357. X        {
  1358. X          STRCPY(display, ".") ;
  1359. X          toclear = 0 ;
  1360. X        }
  1361. X      else if (strlen(display) < disp_length[(int) base])
  1362. X        STRNCAT(display, ".", 1) ;
  1363. X      pointed = 1 ;
  1364. X    }
  1365. X  set_item(DISPLAYITEM, display) ;
  1366. X  disp_val = convert_display() ;    /* Convert input to a number. */
  1367. X}
  1368. X
  1369. X
  1370. Xdo_portion()
  1371. X{
  1372. X  switch (current)
  1373. X    {
  1374. X      case 'U' : disp_val = fabs(disp_val) ;       /* ABS. */
  1375. X                 break ;
  1376. X      case 'F' : disp_val -= (int) disp_val ;      /* FRAC. */
  1377. X                 break ;
  1378. X      case 'I' : disp_val = (int) disp_val ;       /* INT. */
  1379. X    }
  1380. X  show_display(disp_val) ;
  1381. X}
  1382. X
  1383. X
  1384. Xdo_set_mode()           /* Set or unset various calculator modes. */
  1385. X{
  1386. X  switch (current)
  1387. X    {
  1388. X      case CCTRL('d') :                                    /* DEG */
  1389. X      case CCTRL('g') :                                    /* GRAD */
  1390. X      case CCTRL('r') : do_trigtype() ;                    /* RAD */
  1391. X                        break ;
  1392. X      case 'h'        : hyperbolic = !hyperbolic ;         /* HYP */
  1393. X                        set_item(HYPITEM, (hyperbolic) ? "HYP " : "    ") ;
  1394. X                        break ;
  1395. X      case 'i'        : inverse = !inverse ;               /* INV */
  1396. X                        set_item(INVITEM, (inverse) ? "INV " : "    ") ;
  1397. X                        break ;
  1398. X      case CCTRL('n') : do_numtype() ;                     /* FIX/SCI */
  1399. X    }
  1400. X  if (rstate) make_registers() ;
  1401. X}
  1402. X
  1403. X
  1404. Xdo_shift()     /* Perform bitwise shift on display value. */
  1405. X{
  1406. X  int n, shift ;
  1407. X  BOOLEAN temp ;
  1408. X
  1409. X  if (current >= '0' && current <= '9')
  1410. X    {
  1411. X      for (n = 0; n < TITEMS; n++)
  1412. X        if (current == buttons[n].value) break ;
  1413. X      shift = char_val(buttons[n].value) ;
  1414. X      temp = ibool(convert_display()) ;
  1415. X      switch (pending)
  1416. X        {
  1417. X          case '<' : temp = temp << shift ;
  1418. X                     break ;
  1419. X          case '>' : temp = temp >> shift ;
  1420. X        }
  1421. X      STRCPY(display, make_number(setbool(temp))) ;
  1422. X      disp_val = last_input = convert_display() ;
  1423. X    }
  1424. X}
  1425. X
  1426. X
  1427. Xdo_sto_rcl()     /* Save/restore value to/from memory register. */
  1428. X{
  1429. X  if (current >= '0' && current <= '9')
  1430. X    switch (pending)
  1431. X      {
  1432. X        case 'r' : disp_val = mem_vals[char_val(current)] ;
  1433. X                   break ;
  1434. X        case 's' : switch (pending_op)
  1435. X                     {
  1436. X                       case '+' : mem_vals[char_val(current)] += disp_val ;
  1437. X                                  break ;
  1438. X                       case '-' : mem_vals[char_val(current)] -= disp_val ;
  1439. X                                  break ;
  1440. X                       case 'x' : mem_vals[char_val(current)] *= disp_val ;
  1441. X                                  break ;
  1442. X                       case '/' : mem_vals[char_val(current)] /= disp_val ;
  1443. X                                  break ;
  1444. X                       case '=' : mem_vals[char_val(current)] = disp_val ;
  1445. X                     }  
  1446. X                   make_registers() ;
  1447. X      }                 
  1448. X  else if (current == '+' || current == '-' ||
  1449. X           current == 'x' || current == '/') pending_op = current ;
  1450. X}
  1451. X
  1452. X
  1453. Xdo_trig()         /* Perform all trigonometric functions. */
  1454. X{
  1455. X  double temp ;
  1456. X
  1457. X  if (!inverse)
  1458. X    {
  1459. X           if (ttype == DEG)  temp = disp_val * M_PI / 180.0 ;
  1460. X      else if (ttype == GRAD) temp = disp_val * M_PI / 200.0 ;
  1461. X      else                    temp = disp_val ;
  1462. X
  1463. X      if (!hyperbolic)
  1464. X        switch (current)
  1465. X          {
  1466. X            case CCTRL('c') : tresults[(int) RAD] = cos(temp) ;    /* cos */
  1467. X                              break ;
  1468. X            case CCTRL('s') : tresults[(int) RAD] = sin(temp) ;    /* sin */
  1469. X                              break ;
  1470. X            case CCTRL('t') : tresults[(int) RAD] = tan(temp) ;    /* tan */
  1471. X          }
  1472. X      else
  1473. X        switch (current)
  1474. X          {
  1475. X            case CCTRL('c') : tresults[(int) RAD] = cosh(temp) ;   /* cosh */
  1476. X                              break ;
  1477. X            case CCTRL('s') : tresults[(int) RAD] = sinh(temp) ;   /* sinh */
  1478. X                              break ;
  1479. X            case CCTRL('t') : tresults[(int) RAD] = tanh(temp) ;   /* tanh */
  1480. X          }
  1481. X
  1482. X      tresults[(int) DEG]  = tresults[(int) RAD] ;
  1483. X      tresults[(int) GRAD] = tresults[(int) RAD] ;
  1484. X    }
  1485. X  else
  1486. X    {
  1487. X      if (!hyperbolic)
  1488. X        switch (current)
  1489. X          {
  1490. X            case CCTRL('c') : disp_val = acos(disp_val) ;     /* acos */
  1491. X                              break ;
  1492. X            case CCTRL('s') : disp_val = asin(disp_val) ;     /* asin */
  1493. SHAR_EOF
  1494. echo "End of part 2"
  1495. echo "File functions.c is continued in part 3"
  1496. echo "3" > s2_seq_.tmp
  1497. exit 0
  1498.  
  1499.