richb@Aus.Sun.COM (Rich Burridge) (01/16/90)
Posting-number: Volume 10, Issue 7 Submitted-by: richb@Aus.Sun.COM (Rich Burridge) Archive-name: calctool24/part02 ---- Cut Here and unpack ---- #!/bin/sh # this is part 2 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file calctool.ps continued # CurArch=2 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 echo "x - Continuing file calctool.ps" sed 's/^X//' << 'SHAR_EOF' >> calctool.ps X% correct place. X X/PSMakeFrames % wx wy width height ix iy iconic => - X{ X [ /IsIcon /IconY /IconX /KCHeight /KCWidth /KCY /KCX ] X { exch def } forall X X% /ScreenHeight /size framebuffer send exch def pop X /ScreenHeight 900 def X X /KFrame [KeyClass] [/Footer false /Label false] X framebuffer /new OpenLookBaseFrame send def X /KC /client KFrame send def X KCWidth KCHeight /lockminsize KC send X calctoolIcon /seticon KFrame send X% IconX X% ScreenHeight FrameHeight sub IconY sub X% 42 64 /reshape /Icon /sendsubframe KFrame send X X /preferredsize KFrame send /FrameHeight exch def X /FrameWidth exch def X X KCX X ScreenHeight FrameHeight sub KCY sub X FrameWidth FrameHeight /reshape KFrame send X X /RFrame [RegClass] framebuffer /new OpenLookPropertyFrame send def X /RC /client RFrame send def X /RCHeight 200 def X KCWidth RCHeight /lockminsize RC send X X /activate KFrame send X X% /map IsIcon 1 eq {/Icon /subframes KFrame send get} {KFrame} ifelse send X% IsIcon 1 eq {/close KFrame send} if X X /map KFrame send X X /activate RFrame send X /place RFrame send X} def X X X% Place a colored text string in the appropriate font at the given X% x,y position in either the main calctool window or the memory X% register window. X X/PSMakeText % string x canvasheight y font color canvas => - X{ X setcanvas X ColorTable exch get setcolor X setfont X sub moveto show X} def X X X/PSSetCursor % type => - X{ X} def X X X% Depending upon the current setting, either show (map) or remove X% (unmap) the memory register window. X X/PSToggleRegCanvas % state => - X{ X 1 eq { /map RFrame send} { /unmap RFrame send} ifelse X} def SHAR_EOF echo "File calctool.ps is complete" chmod 0444 calctool.ps || echo "restore of calctool.ps fails" set `wc -c calctool.ps`;Sum=$1 if test "$Sum" != "6058" then echo original size 6058, current size $Sum;fi echo "x - extracting patchlevel.h (Text)" sed 's/^X//' << 'SHAR_EOF' > patchlevel.h && X X/* @(#)patchlevel.h 1.12 89/12/21 X * X * This is the current patch level for this version of calctool. X * X * Copyright (c) Rich Burridge. X * Sun Microsystems, Australia - All rights reserved. X * X * Permission is given to distribute these sources, as long as the X * copyright messages are not removed, and no monies are exchanged. X * X * No responsibility is taken for any errors or inaccuracies inherent X * either to the comments or the code of this program, but if X * reported to me then an attempt will be made to fix them. X */ X X#define PATCHLEVEL 4 SHAR_EOF chmod 0444 patchlevel.h || echo "restore of patchlevel.h fails" set `wc -c patchlevel.h`;Sum=$1 if test "$Sum" != "563" then echo original size 563, current size $Sum;fi echo "x - extracting .calctoolrc (Text)" sed 's/^X//' << 'SHAR_EOF' > .calctoolrc && X# X# @(#).calctoolrc 1.4 89/12/13 X# X# This is a sample .calctoolrc file. You should use this as a basis for X# creating your own .calctoolrc files. X# X# Process the .calctoolrc file. There are currently four types of X# records to look for: X# X# 1) Those starting with a hash in the first column are comments. X# X# 2) Lines starting with 'c' or 'C' in the first column are X# definitions for constants. The cC is followed by a digit in X# the range 0-9, then a space. This is followed by a number X# in fixed or scientific notation. Following this is an optional X# comment, which if found, will be used in the popup menu for X# the constants. If the comment is present, there must be at X# least one space between this and the preceding number. X# X# 3) Those starting with a 'f' or a 'F' in the first column are X# definitions for functions. The fF is followed by a digit in X# the range 0-9, then a space. This is followed by a function X# definition. Following this is an optional comment, which if X# found, will be used in the popup menu for the functions. X# If the comment is present, there must be at least one space X# between this and the preceding function definition. X# X# 4) Lines starting with a 'r' or a 'R' in the first column are X# definitions for the initial contents of the calculators X# memory registers. The rR is followed by a digit in the X# range 0-9, then a space. This is followed by a number in X# fixed or scientific notation. The rest of the line is ignored. X# X# All other lines are ignored. X# X# Two other things to note. There should be no embedded spaces in X# the function definitions, and whenever a backslash is found, that X# and the following character signify a control character, for X# example \g would be ascii 7. X# X# CONSTANTS X# X# This is a set of nine physical constants which could be used instead X# of those provided by default. If you don't wish to use these, then X# you should define your own, or comment these out. X# X Xc0 299792458 Speed of light in a vacuum (c). X Xc1 6.626176E-34 Planck's constant (h). X Xc2 6.672E-11 Gravitational constant (G). X Xc3 1.6021892E-19 Elementary charge (e). X Xc4 9.109534E-31 Electron rest mass (me). X Xc5 1.6605655E-27 Atomic mass unit (u). X Xc6 6.022045E23 Avogadro constant (Na). X Xc7 1.380662E-23 Boltzmann constant (k). X Xc8 0.02241383 Molar volume of ideal gas at s. t. p. (Vm). X X# FUNCTIONS. X# X# This is a sample set of functions which are assigned to the FUN key. X# X# On a suggestion from Charles Tierney, these functions are taken from X# the power calculation section of the March 1989 edition of the Sun X# Configuration Guide. X# X# f0 - Calculate AC Watts (Formula A). X# X# 1 X# P(true) = P(DC) x ------- X# PS(Eff) X# X# where P(DC) = total DC power in watts [user-calculated] - register 0. X# X# result placed in register 1. X Xf0 r0x1.43=s1 Calculate AC Watts (Formula A). X X# f1 - Calculate Thermal Dissipation (Formula B). X# X# BTU X# BTU(nom) = P(true) x 3.412 ----- X# watt X# X# where P(true) = true AC power in watts from above - register 1. X# X# result placed in register 2. X Xf1 r1x3.412=s2 Calculate Thermal Dissipation (Formula B). X X# f2 - Calculate Volt - Amps (Formula C). X# X# 1 X# VA = P(true) x ---- X# PF X# X# where P(true) is from the formula above - register 1. X# X# and PF is the Power Factor - register 3. X# X# Sun-3/60/140/160/180 and Sun-4/110 = 0.65 X# Sun-3/260/280 and Sun-4/260/280 = 0.715 X# Sun-3/150 and Sun-4/150 = 0.9 (at full load). X# X# result placed in register 4. X Xf2 1/r3xr1=s4 Calculate Volt - Amps (Formula C). X X# X# REGISTERS. X# X# This is a sample set of initial register values. You probably X# don't want to use these, so you should define your own or comment X# these out. X Xr0 0.4971 Log10 of pi. X Xr1 0.4343 Log10 of e. X Xr3 57.29578 Degrees in radian. SHAR_EOF chmod 0444 .calctoolrc || echo "restore of .calctoolrc fails" set `wc -c .calctoolrc`;Sum=$1 if test "$Sum" != "4184" then echo original size 4184, current size $Sum;fi echo "x - extracting graphics.c (Text)" sed 's/^X//' << 'SHAR_EOF' > graphics.c && X X/* @(#)graphics.c 1.12 89/12/21 X * X * These are the independent graphics routines used by calctool. X * X * Copyright (c) Rich Burridge. X * Sun Microsystems, Australia - All rights reserved. X * X * Permission is given to distribute these sources, as long as the X * copyright messages are not removed, and no monies are exchanged. X * X * No responsibility is taken for any errors or inaccuracies inherent X * either to the comments or the code of this program, but if X * reported to me then an attempt will be made to fix them. X */ X X#include "calctool.h" X#include "color.h" X#include "extern.h" X X Xbut_text(row, column, portion, state) Xint row, column, portion ; Xenum but_state state ; X{ X enum font_type butfont ; X int i, n ; X X n = row*BCOLS*2 + column*2 + portion ; X if (buttons[n].color == GREY) return ; X get_label(n) ; X for (spaces = 0, i = 0; i < strlen(pstr); i++) X if (pstr[i] == ' ') spaces++ ; X x = chxoff[spaces] ; X y = (n & 1) ? 40 : 18 ; X if (spaces == 3) y += 4 ; X butfont = (spaces == 3) ? BFONT : NFONT ; X if (state == NORMAL) X color = (!iscolor & portion) ? WHITE : BLACK ; X if (state == INVERTED) X color = (portion) ? BLACK : WHITE ; X drawtext(column*(BWIDTH+BGAP)+BBORDER+x, X DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+y, KEYCANVAS, butfont, color, pstr) ; X} X X Xdo_repaint() /* Redraw the calctool canvas[es]. */ X{ X make_canvas(0) ; X} X X Xdrawbox(x, y, width, height) Xint x, y, width, height ; X{ X drawline(x, y, x+width, y) ; X drawline(x, y, x, y+height) ; X drawline(x, y+height, x+width, y+height) ; X drawline(x+width, y, x+width, y+height) ; X} X X Xdraw_button(row, column, portion, state) Xint row, column, portion ; Xenum but_state state ; X{ X int n ; X X n = row*BCOLS*2 + column*2 + portion ; X if (!portion) X { X color = (iscolor) ? buttons[n].color : WHITE ; X drawbox(column*(BWIDTH+BGAP)+BBORDER, X DISPLAY+row*(BHEIGHT+BGAP)+BBORDER, BWIDTH, BHEIGHT) ; X fillbox(column*(BWIDTH+BGAP)+BBORDER+1, X DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+1, KEYCANVAS, X 42, 50, 1, color) ; X } X else X { X drawbox(column*(BWIDTH+BGAP)+BBORDER+5, X DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+26, 34, 21) ; X color = (iscolor) ? buttons[n].color : BLACK ; X fillbox(column*(BWIDTH+BGAP)+BBORDER+6, X DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+27, KEYCANVAS, X 32, 19, 1, color) ; X } X but_text(row, column, portion, state) ; X} X X Xfillbox(x, y, window, width, height, boundry, color) Xenum can_type window ; Xint x, y, width, height, boundry, color ; X{ X if (boundry) X { X color_area(x, y, width, height, WHITE) ; X color_area(x+1, y+1, width-2, height-2, color) ; X } X else color_area(x, y, width, height, color) ; X} X X Xget_menu_value() /* Get menu value if valid right mouse press. */ X{ X int i, n, val ; X X n = row*BCOLS*2 + column*2 + portion ; X for (i = 0; i < MAXMENUS; i++) X if (buttons[n].value == validmenu[i]) X { X val = do_menu((enum menu_type) i) ; X if (val) handle_menu_selection(i, val) ; X break ; X } X} X X Xgrey_buttons(base) /* Grey out numeric buttons depending upon base. */ Xenum base_type base ; X{ X char val ; X int column, i, n, portion, row ; X X if (gtype == TTY) return ; X for (i = 0; i < 16; i++) X { X val = digits[i] ; X for (n = 0; n < TITEMS; n++) X if (val == buttons[n].value) break ; X if (i < basevals[(int) base]) X { X if (i < 10) buttons[n].color = LBLUE ; X else buttons[n].color = PINK ; X } X else buttons[n].color = GREY ; X row = n / (BCOLS*2) ; X column = (n - (row*BCOLS*2)) / 2 ; X portion = n & 1 ; X draw_button(row, column, portion, NORMAL) ; X } X} X X Xhandle_down_event(type) Xint type ; X{ X x = curx ; X y = cury ; X if (!down) X { X if (pending_op == '?') X { X down = type ; X return ; X } X for (row = 0; row < BROWS; row++) X for (column = 0; column < BCOLS; column++) X if ((x > (column*(BWIDTH+BGAP)+BBORDER)) && X (x < (column*(BWIDTH+BGAP)+BBORDER+BWIDTH)) && X ((y - DISPLAY) > (row*(BHEIGHT+BGAP)+BBORDER)) && X ((y - DISPLAY) < (row*(BHEIGHT+BGAP)+BBORDER+BHEIGHT))) X { X portion = (y - DISPLAY - BBORDER - X (row*(BHEIGHT+BGAP))) / (BHEIGHT/2) ; X inv_but(row, column, portion, INVERTED) ; X down = type ; X return ; X } X } X} X X Xhandle_menu_selection(menu, item) /* Process right button menu selection. */ Xint menu, item ; X{ X pending = validmenu[menu] ; X current = num_names[item-1][0] ; X do_pending() ; X down = 0 ; X inv_but(row, column, portion, NORMAL) ; X} X X Xinv_but(row, column, portion, state) Xint row, column, portion ; Xenum but_state state ; X{ X int n ; X X n = row*BCOLS*2 + column*2 + portion ; X if (pending_op != '?') X { X if (state == NORMAL) X if (iscolor) color = buttons[n].color ; X else color = (portion) ? BLACK : WHITE ; X if (state == INVERTED) X color = (portion) ? WHITE : BLACK ; X fillbox(column*(BWIDTH+BGAP)+BBORDER+6, X DISPLAY+row*(BHEIGHT+BGAP)+BBORDER+5+(portion*22), X KEYCANVAS, 32, 19, portion, color) ; X but_text(row, column, portion, state) ; X } X} X X Xmake_canvas(toggle) Xint toggle ; X{ X if (toggle) tstate = !tstate ; X color = (iscolor) ? GREY : WHITE ; X clear_canvas(KEYCANVAS, color) ; X if (iscolor) color_area(0, 0, TWIDTH, DISPLAY, WHITE) ; X drawline(0, DISPLAY, TWIDTH, DISPLAY) ; X for (row = 0; row < BROWS; row++) X for (column = 0; column < BCOLS; column++) X for (portion = 0; portion < 2; portion++) X draw_button(row, column, portion, NORMAL) ; X X set_item(BASEITEM,base_str[(int) base]) ; X set_item(DISPLAYITEM, display) ; X set_item(NUMITEM, dtype_str[(int) dtype]) ; X set_item(OPITEM, items[(int) OPITEM].text) ; X set_item(TTYPEITEM,ttype_str[(int) ttype]) ; X set_item(HYPITEM, (hyperbolic) ? "HYP " : " ") ; X set_item(INVITEM, (inverse) ? "INV " : " ") ; X make_registers() ; X} X X Xmake_menus() /* Create the popup menus used by the graphics versions. */ X{ X X/* There are nine popup menus. These are associated with the following keys: X * X * ACC - range of possible accuracies (0 - 9). X * X * CON - constant values plus associated comments, if present. X * X * EXCH - list of register numbers (0 - 9). X * X * FUN - function definitions plus associated comments, if present. X * X * HELP - contains all the keys in the calculator. X * X * < - range of possible left shift values (0 - 9). X * X * > - range of possible right shift values (0 - 9). X * X * RCL - list of register numbers (0 - 9). X * X * STO - list of register numbers (0 - 9). X */ X X create_menu(M_ACC) ; /* Accuracies. */ X create_menu(M_CON) ; /* Constant definitions. */ X create_menu(M_EXCH) ; /* Register exchange. */ X create_menu(M_FUN) ; /* Function definitions. */ X create_menu(M_LSHIFT) ; /* Left shift. */ X create_menu(M_RSHIFT) ; /* Right shift. */ X create_menu(M_RCL) ; /* Register recall. */ X create_menu(M_STO) ; /* Register store. */ X} X X Xmake_registers() /* Calculate memory register frame values. */ X{ X char line[MAXLINE] ; /* Current memory register line. */ X int n ; X X if (!rstate) return ; X clear_canvas(REGCANVAS, WHITE) ; X drawtext(15, 20, REGCANVAS, NFONT, BLACK, "Memory Registers") ; X for (n = 0; n < MAXREGS; n++) X { X SPRINTF(line, "%1d %s", n, make_number(mem_vals[n])) ; X drawtext(15, 40+15*n, REGCANVAS, NFONT, BLACK, line) ; X } X} X X Xprocess_event(type) /* Process this event. */ Xint type ; X{ X int i, n ; X X n = row*BCOLS*2 + column*2 + portion ; X switch (type) X { X case CFRAME_REPAINT : make_canvas(0) ; X set_item(BASEITEM, base_str[(int) base]) ; X set_item(TTYPEITEM, ttype_str[(int) ttype]) ; X break ; X case EXIT_WINDOW : if (pending_op != '?') X if (n >= 0 && n <= (NOBUTTONS*2)) X { X draw_button(row, column, portion, NORMAL) ; X if (!portion) X draw_button(row, column, 1, NORMAL) ; X } X down = 0 ; X break ; X case KEYBOARD : nextc = cur_ch ; X for (n = 0; n < TITEMS; n++) X if (nextc == buttons[n].value) break ; X if (n == TITEMS) return ; X if (n >= 0 && n <= TITEMS) X process_item(n) ; X break ; X case LEFT_DOWN : X case MIDDLE_DOWN : X case RIGHT_DOWN : handle_down_event(type) ; X if (type == RIGHT_DOWN) get_menu_value() ; X break ; X case LEFT_UP : X case MIDDLE_UP : X case RIGHT_UP : x = curx ; X y = cury ; X if ((type == LEFT_UP && down == LEFT_DOWN) || X (type == MIDDLE_UP && down == MIDDLE_DOWN) || X (type == RIGHT_UP && down == RIGHT_DOWN)) X { X if (pending_op != '?' && n <= (NOBUTTONS*2)) X inv_but(row, column, portion, NORMAL) ; X down = 0 ; X if (n >= 0 && n <= (NOBUTTONS*2)) X process_item(n) ; X } X break ; X case RFRAME_REPAINT : make_registers() ; X break ; X case TAKE_FROM_SHELF : handle_selection() ; X if (issel) X for (i = 0 ; i < strlen(selection); i++) X for (n = 0; n < TITEMS; n++) X if (selection[i] == buttons[n].value) X { X process_item(n) ; X break ; X } X break ; X case PUT_ON_SHELF : get_display() ; X break ; X case DIED : exit(0) ; X } X} X X Xset_item(itemno, str) Xenum item_type itemno ; Xchar *str ; X{ X enum font_type font ; X char *old_text ; X int x, y ; X X old_text = items[(int) itemno].text ; X if (itemno == DISPLAYITEM) X x = 5+(MAX_DIGITS - strlen(old_text))*nfont_width ; X else x = items[(int) itemno].x ; X y = items[(int) itemno].y ; X font = items[(int) itemno].font ; X old_text = items[(int) itemno].text ; X drawtext(x, y, KEYCANVAS, font, WHITE, old_text) ; X X if (itemno == DISPLAYITEM) x = 5+(MAX_DIGITS - strlen(str))*nfont_width ; X X drawtext(x, y, KEYCANVAS, font, BLACK, str) ; X STRCPY(items[(int) itemno].text, str) ; X} SHAR_EOF chmod 0444 graphics.c || echo "restore of graphics.c fails" set `wc -c graphics.c`;Sum=$1 if test "$Sum" != "11290" then echo original size 11290, current size $Sum;fi echo "x - extracting display.c (Text)" sed 's/^X//' << 'SHAR_EOF' > display.c && X X/* @(#)display.c 1.8 89/11/01 X * X * Display manipulation routines used by calctool. X * X * Copyright (c) Rich Burridge. X * Sun Microsystems, Australia - All rights reserved. X * X * Basic algorithms, copyright (c) Ed Falk. X * Sun Microsystems, Mountain View. X * X * Permission is given to distribute these sources, as long as the X * copyright messages are not removed, and no monies are exchanged. X * X * No responsibility is taken for any errors or inaccuracies inherent X * either to the comments or the code of this program, but if X * reported to me then an attempt will be made to fix them. X */ X X#include "calctool.h" X#include "color.h" X#include "extern.h" X X Xchar_val(chr) Xchar chr ; X{ X if (chr >= '0' && chr <= '9') return(chr - '0') ; X else if (chr >= 'a' && chr <= 'f') return(chr - 'a' + 10) ; X else return(-1) ; X} X X Xclear_display() X{ X int i ; X X pointed = 0 ; X toclear = 1 ; X STRCPY(display, "0.") ; X for (i = 0; i < accuracy; i++) STRNCAT(display, "0", 1) ; X set_item(DISPLAYITEM, display) ; X hyperbolic = inverse = 0 ; X set_item(HYPITEM, " ") ; X set_item(INVITEM, " ") ; X disp_val = 0.0 ; X} X X Xdouble Xconvert_display() /* Convert input string into a double. */ X{ X int exp, exp_sign, i, inum ; X double val ; X char *optr ; X X val = 0.0 ; X exp = 0 ; X optr = display ; X while ((inum = char_val(*optr)) >= 0) X { X val = val * basevals[(int) base] + inum ; X *optr++ ; X } X X if (*optr == '.') X for (i = 1; (inum = char_val(*++optr)) >= 0; i++) X val += inum / powers[i][(int) base] ; X X while (*optr == ' ') optr++ ; X X if (*optr != '\0') X { X if (*optr == '-') exp_sign = -1 ; X else exp_sign = 1 ; X X while ((inum = char_val(*++optr)) >= 0) X exp = exp * basevals[(int) base] + inum ; X } X exp *= exp_sign ; X X if (key_exp) X val *= pow((double) basevals[(int) base], (double) exp) ; X return(val) ; X} X X Xget_label(n) Xint n ; X{ X if (tstate) X switch (buttons[n].value) X { X case CCTRL('c') : X case CCTRL('d') : X case CCTRL('e') : X case CCTRL('f') : X case CCTRL('g') : X case CCTRL('n') : X case CCTRL('r') : X case CCTRL('s') : X case CCTRL('t') : SPRINTF(pstr, "^%c ", buttons[n].value + 96) ; X break ; X case CCTRL('h') : STRCPY(pstr, "bsp ") ; X break ; X case '\177' : STRCPY(pstr, "del ") ; X break ; X default : SPRINTF(pstr, "%c ", buttons[n].value) ; X } X else STRCPY(pstr, buttons[n].str) ; X} X X Xinitialise() X{ X error = 0 ; /* Currently no display error. */ X cur_op = '?' ; /* No arithmetic operator defined yet. */ X old_cal_value = '?' ; X result = 0.0 ; /* No previous result yet. */ X last_input = 0.0 ; X} X X Xchar * Xmake_fixed(number, cmax) /* Convert fixed number. */ Xdouble number ; /* Value to convert. */ Xint cmax ; /* Maximum characters to generate. */ X{ X char *optr ; X double val ; X int ndig ; /* Total number of digits to generate. */ X int ddig ; /* Number of digits to left of . */ X int dval ; X X optr = fnum ; X val = fabs(number) ; X if (number < 0.0) *optr++ = '-' ; X val += .5 / powers[accuracy][(int) base] ; X X if (val < 1.0) X { X ddig = 0 ; X *optr++ = '0' ; X cmax-- ; X } X else X { X for (ddig = 0; val >= 1.0; ddig++) X val /= powers[1][(int) base] ; X } X X ndig = MIN(ddig + accuracy, --cmax) ; X X while (ndig-- > 0) X { X if (ddig-- == 0) *optr++ = '.' ; X val *= powers[1][(int) base] ; X dval = val ; X *optr++ = digits[dval] ; X val -= (int) val ; X } X *optr++ = '\0' ; X toclear = 1 ; X pointed = 0 ; X return(fnum) ; X} X X Xchar * Xmake_number(number) /* Convert display value to current base. */ Xdouble number ; /* Value to convert. */ X{ X double val ; X X if (isinf(number) || isnan(number)) X { X STRCPY(display, "Error") ; X error = 1 ; X set_item(OPITEM, "CLR") ; X return(display) ; X } X X val = fabs(number) ; X if (dtype == SCI || X dtype == FIX && val != 0.0 && (val > max_fix[(int) base] || X val < exp_p1[accuracy][(int) base])) X return(make_scientific(number)) ; X else return(make_fixed(number, MAX_DIGITS)) ; X} X X Xchar * Xmake_scientific(number) /* Convert scientific number. */ Xdouble number ; /* Value to convert. */ X{ X char fixed[MAX_DIGITS+1] ; X char *optr ; X double mant ; /* Mantissa */ X double val ; X int exp = 0 ; /* Exponent */ X int i ; X int eng = 0 ; /* Scientific not engineering value. */ X double atmp ; X X optr = snum ; X val = fabs(number) ; X if (number < 0.0) *optr++ = '-' ; X mant = val ; X atmp = 1.0 / powers[10][(int) base] ; X X if (mant != 0.0) X { X while (mant >= powers[10][(int) base]) X { X exp += 10 ; X mant *= atmp ; X } X X while ((!eng && mant >= powers[1][(int) base]) || X (eng && (mant >= powers[3][(int) base] || exp % 3 != 0))) X { X exp += 1 ; X mant /= powers[1][(int) base] ; X } X X while (mant < atmp) X { X exp -= 10 ; X mant *= powers[10][(int) base] ; X } X X while (mant < 1.0 || (eng && exp % 3 != 0)) X { X exp -= 1 ; X mant *= powers[1][(int) base] ; X } X } X X STRCPY(fixed, make_fixed(mant, MAX_DIGITS-6)) ; X for (i = 0; i < strlen(fixed); i++) *optr++ = fixed[i] ; X X *optr++ = 'e' ; X X if (exp < 0) X { X exp = -exp ; X *optr++ = '-' ; X } X else *optr++ = '+' ; X X if ((*optr = digits[exp / ((int) powers[2][(int) base])]) != '0') X optr++ ; X exp %= (int) powers[2][(int) base] ; X *optr++ = digits[exp / ((int) powers[1][(int) base])] ; X exp %= (int) powers[1][(int) base] ; X *optr++ = digits[exp] ; X *optr++ = '\0' ; X toclear = 1 ; X pointed = 0 ; X return(snum) ; X} X X Xprocess_item(n) Xint n ; X{ X int i,isvalid ; X X if (n < 0 || n > TITEMS) return ; X X current = buttons[n].value ; X if (current == 'X') current = 'x' ; /* Reassign "extra" values. */ X if (current == '*') current = 'x' ; X if (current == '\015') current = '=' ; X if (current == 'Q') current = 'q' ; X X if (error) X { X isvalid = 0 ; /* Must press a valid key first. */ X for (i = 0; i < MAXVKEYS; i++) X if (current == validkeys[i]) isvalid = 1 ; X if (pending == '?') isvalid = 1 ; X if (!isvalid) return ; X error = 0 ; X } X X if (pending) X { X for (n = 0; n < TITEMS; n++) X if (pending == buttons[n].value) break ; X } X switch (buttons[n].opdisp) X { X case OP_SET : set_item(OPITEM, buttons[n].str) ; X break ; X case OP_CLEAR : if (error) set_item(OPITEM, "CLR") ; X else set_item(OPITEM, "") ; X } X (*buttons[n].func)() ; X} X X Xshow_display(val) Xdouble val ; X{ X if (!error) X { X STRCPY(display, make_number(val)) ; X set_item(DISPLAYITEM, display) ; X } X} SHAR_EOF chmod 0444 display.c || echo "restore of display.c fails" set `wc -c display.c`;Sum=$1 if test "$Sum" != "7188" then echo original size 7188, current size $Sum;fi echo "x - extracting functions.c (Text)" sed 's/^X//' << 'SHAR_EOF' > functions.c && X X/* @(#)functions.c 1.7 89/11/01 X * X * This file contains the seperate functions used by calctool, X * whenever a calculator button is pressed. X * X * Copyright (c) Rich Burridge. X * Sun Microsystems, Australia - All rights reserved. X * X * Basic algorithms, copyright (c) Ed Falk. X * Sun Microsystems, Mountain View. X * X * Permission is given to distribute these sources, as long as the X * copyright messages are not removed, and no monies are exchanged. X * X * No responsibility is taken for any errors or inaccuracies inherent X * either to the comments or the code of this program, but if X * reported to me then an attempt will be made to fix them. X */ X X#include "calctool.h" X#include "color.h" X#include "extern.h" X XBOOLEAN ibool() ; Xdouble setbool() ; X X Xdo_accuracy() /* Set display accuracy. */ X{ X if (current >= '0' && current <= '9') X { X accuracy = char_val(current) ; X make_registers() ; X } X} X X Xdo_base() /* Change the current base setting. */ X{ X switch (current) X { X case 'B' : base = BIN ; X break ; X case 'O' : base = OCT ; X break ; X case 'D' : base = DEC ; X break ; X case 'H' : base = HEX ; X } X grey_buttons(base) ; X set_item(BASEITEM, base_str[(int) base]) ; X show_display(disp_val) ; X if (rstate) make_registers() ; X} X X Xdo_calculation() /* Perform arithmetic calculation and display result. */ X{ X if (current == '=' && old_cal_value == '=') X if (new_input) result = last_input ; X else disp_val = last_input ; X X if (current != '=' && old_cal_value == '=') cur_op = '?' ; X switch (cur_op) X { X case CCTRL('c') : /* cos. */ X case CCTRL('s') : /* sin. */ X case CCTRL('t') : /* tan. */ X case '?' : result = disp_val ; /* Undefined. */ X break ; X case '+' : result += disp_val ; /* Addition. */ X break ; X case '-' : result -= disp_val ; /* Subtraction. */ X break ; X case 'x' : result *= disp_val ; /* Multiplication. */ X break ; X case '/' : result /= disp_val ; /* Division. */ X break ; X case '%' : result *= disp_val * 0.01 ; /* % */ X break ; X case 'Y' : result = pow(result, disp_val) ; /* y^x */ X break ; X case '&' : result = setbool(ibool(result) & /* AND */ X ibool(disp_val)) ; X break ; X case '|' : result = setbool(ibool(result) | /* OR */ X ibool(disp_val)) ; X break ; X case '^' : result = setbool(ibool(result) ^ /* XOR */ X ibool(disp_val)) ; X break ; X case 'n' : result = setbool(~(ibool(result) ^ /* XNOR */ X ibool(disp_val))) ; X break ; X case '=' : break ; /* Equals. */ X } X show_display(result) ; X if (!(current == '=' && old_cal_value == '=')) last_input = disp_val ; X X disp_val = result ; X if (current != '=') cur_op = current ; X old_cal_value = current ; X new_input = key_exp = 0 ; X} X X Xdo_clear() /* Clear the calculator display and re-initialise. */ X{ X clear_display() ; X if (error) set_item(DISPLAYITEM, "") ; X initialise() ; X} X X Xdo_constant() X{ X if (current >= '0' && current <= '9') X { X disp_val = con_vals[char_val(current)] ; X show_display(disp_val) ; X } X} X X Xdo_delete() /* Remove the last numeric character typed. */ X{ X if (strlen(display)) display[strlen(display)-1] = '\0' ; X X/* If we were entering a scientific number, and we have backspaced over X * the exponent sign, then this reverts to entering a fixed point number. X */ X X if (key_exp && !(index(display, '+'))) X { X key_exp = 0 ; X display[strlen(display)-1] = '\0' ; X set_item(OPITEM, "") ; X } X X set_item(DISPLAYITEM, display) ; X disp_val = convert_display() ; /* Convert input to a number. */ X} X X Xdo_exchange() /* Exchange display with memory register. */ X{ X double temp ; X X if (current >= '0' && current <= '9') X { X temp = disp_val ; X disp_val = mem_vals[char_val(current)] ; X mem_vals[char_val(current)] = temp ; X make_registers() ; X } X} X X Xdo_expno() /* Get exponential number. */ X{ X if (!new_input) X { X STRCPY(display, "1.0 +") ; X new_input = pointed = 1 ; X } X else if (!pointed) X { X STRNCAT(display, ". +", 3) ; X pointed = 1 ; X } X else STRNCAT(display, " +", 2) ; X key_exp = 1 ; X exp_posn = index(display, '+') ; X set_item(DISPLAYITEM, display) ; X disp_val = convert_display() ; /* Convert input to a number. */ X} X X Xdouble Xdo_factorial(val) /* Calculate the factorial of val. */ Xdouble val ; X{ X double a ; X int i ; X X if (val == (int) val) X { X i = val ; X a = 1.0 ; X while ((i > 0) && (a != HUGE)) a *= (float) i-- ; X } X else X { X a = gamma(val+1) ; X a = exp(a) ; X if (signgam) a = -a ; X } X return (a) ; X} X X Xdo_function() /* Perform a user defined function. */ X{ X int fno, i, n ; X X pending = 0 ; X if (current >= '0' && current <= '9') X { X fno = char_val(current) ; X for (i = 0 ; i < strlen(fun_vals[fno]); i++) X for (n = 0; n < TITEMS; n++) X if (fun_vals[fno][i] == buttons[n].value) X { X process_item(n) ; X break ; X } X } X} X X Xdo_help() /* Show online help facility. */ X{ X char help_str[MAXLINE], nextline[MAXLINE], *p ; X int n, y ; X X if (pending_op == '?') /* HELP. */ X { X if (ishelp) ishelp++ ; X pending_op = '=' ; X make_canvas(0) ; X set_cursor(MAINCURSOR) ; X } X else X { X clear_canvas(KEYCANVAS, WHITE) ; X y = 20 ; X if (!ishelp) X drawtext(5, y, KEYCANVAS, NFONT, BLACK, "No help file found.") ; X else X { X for (n = 0; n < TITEMS; n++) X if (current == buttons[n].value) break ; X color = (iscolor) ? buttons[n].color : WHITE ; X clear_canvas(KEYCANVAS, color) ; X SPRINTF(help_str, "_%s_\n", buttons[n].str) ; X rewind(hfd) ; X y = 15 ; X p = fgets(nextline, BUFSIZ, hfd) ; X if (EQUAL(p, "_calctool.help_\n")) X { X while (p = fgets(nextline, BUFSIZ, hfd)) X if (*p == '_' && EQUAL(p, help_str)) break ; X if (!p) drawtext(5, y, KEYCANVAS, NFONT, BLACK, X "No help for this item.") ; X for (;;) X { X FGETS(nextline, BUFSIZ, hfd) ; X if (nextline[0] == '_') break ; X nextline[strlen(nextline)-1] = '\0' ; X drawtext(5, y, KEYCANVAS, NFONT, BLACK, nextline) ; X y += 15 ; X } X } X else drawtext(5, y, KEYCANVAS, NFONT, BLACK, X "Invalid help file given.") ; X } X drawtext(5, y+25, KEYCANVAS, NFONT, BLACK, X "Click LEFT or press any valid key.") ; X pending_op = '?' ; X return ; X } X} X X Xdo_immediate() X{ X switch (current) X { X case '[' : disp_val = setbool(ibool(disp_val)) ; /* &32 */ X break ; X case ']' : disp_val = setbool(ibool(disp_val) & 0xffff) ; /* &16 */ X break ; X case '{' : disp_val = exp(disp_val) ; /* e^x */ X break ; X case '}' : disp_val = exp(M_LN10*disp_val) ; /* 10^x */ X break ; X case 'N' : disp_val = log(disp_val) ; /* ln */ X break ; X case 'G' : disp_val = log10(disp_val) ; /* log */ X break ; X case 'S' : disp_val = sqrt(disp_val) ; /* SQRT */ X break ; X case '~' : disp_val = setbool(~ibool(disp_val)) ; /* NOT */ X break ; X case 'R' : disp_val = 1.0 / disp_val ; /* 1/x */ X break ; X case '!' : disp_val = do_factorial(disp_val) ; /* x! */ X break ; X case '@' : disp_val *= disp_val ; /* x^2 */ X break ; X case 'C' : if (key_exp) /* CHS */ X { X if (*exp_posn == '+') *exp_posn = '-' ; X else *exp_posn = '+' ; X set_item(DISPLAYITEM, display) ; X disp_val = convert_display() ; X key_exp = 0 ; X } X else disp_val = -disp_val ; X } X show_display(disp_val) ; X} X X Xdo_keys() /* Display/undisplay the calctool key values. */ X{ X make_canvas(1) ; X} X X Xdo_number() X{ X int n ; X static int maxvals[4] = {1, 7, 9, 15} ; X X n = current - '0' ; X if (base == HEX && current >= 'a' && current <= 'f') X n = current - 'a' + 10 ; X if (n > maxvals[(int) base]) return ; X X if (toclear) X { X SPRINTF(display, "%c", current) ; X toclear = 0 ; X } X else if (strlen(display) < disp_length[(int) base]) X STRNCAT(display, ¤t, 1) ; X set_item(DISPLAYITEM, display) ; X disp_val = convert_display() ; /* Convert input to a number. */ X new_input = 1 ; X} X X Xdo_numtype() /* Set number type (fixed or scientific). */ X{ X int n ; X X if (dtype == FIX) dtype = SCI ; X else dtype = FIX ; X n = row*BCOLS*2 + column*2 + portion ; X STRCPY(buttons[n].str, (dtype == FIX) ? "SCI " : "FIX ") ; X set_item(NUMITEM, dtype_str[(int) dtype]) ; X draw_button(row, column, 0, NORMAL) ; X draw_button(row, column, 1, NORMAL) ; X show_display(disp_val) ; X} X X Xdo_pending() X{ X grey_buttons(HEX) ; /* Reshow all the keys. */ X switch (pending) X { X case '#' : do_constant() ; /* CON */ X break ; X case CCTRL('e') : do_exchange() ; /* EXCH */ X break ; X case CCTRL('f') : do_function() ; /* FUN */ X break ; X case 's' : /* STO */ X case 'r' : do_sto_rcl() ; /* RCL */ X if (pending_op == '+' || pending_op == '-' || X pending_op == 'x' || pending_op == '/') return ; X break ; X case '<' : /* < */ X case '>' : do_shift() ; /* > */ X break ; X case 'A' : do_accuracy() ; /* ACC */ X break ; X case '?' : do_help() ; /* ? */ X if (pending_op == '?') return ; X break ; X default : if (!pending) X { X pending = current ; X pending_op = '=' ; X if (pending == '?') set_cursor(HELPCURSOR) ; X if (pending == '?' && (ishelp <= 1)) do_pending() ; X return ; X } X } X show_display(disp_val) ; X if (error) set_item(OPITEM, "CLR") ; X else set_item(OPITEM, "") ; X pending = 0 ; X grey_buttons(base) ; /* Just show numeric keys for current base. */ X} X X Xdo_point() /* Handle numeric point. */ X{ X if (!pointed) X { X if (toclear) X { X STRCPY(display, ".") ; X toclear = 0 ; X } X else if (strlen(display) < disp_length[(int) base]) X STRNCAT(display, ".", 1) ; X pointed = 1 ; X } X set_item(DISPLAYITEM, display) ; X disp_val = convert_display() ; /* Convert input to a number. */ X} X X Xdo_portion() X{ X switch (current) X { X case 'U' : disp_val = fabs(disp_val) ; /* ABS. */ X break ; X case 'F' : disp_val -= (int) disp_val ; /* FRAC. */ X break ; X case 'I' : disp_val = (int) disp_val ; /* INT. */ X } X show_display(disp_val) ; X} X X Xdo_set_mode() /* Set or unset various calculator modes. */ X{ X switch (current) X { X case CCTRL('d') : /* DEG */ X case CCTRL('g') : /* GRAD */ X case CCTRL('r') : do_trigtype() ; /* RAD */ X break ; X case 'h' : hyperbolic = !hyperbolic ; /* HYP */ X set_item(HYPITEM, (hyperbolic) ? "HYP " : " ") ; X break ; X case 'i' : inverse = !inverse ; /* INV */ X set_item(INVITEM, (inverse) ? "INV " : " ") ; X break ; X case CCTRL('n') : do_numtype() ; /* FIX/SCI */ X } X if (rstate) make_registers() ; X} X X Xdo_shift() /* Perform bitwise shift on display value. */ X{ X int n, shift ; X BOOLEAN temp ; X X if (current >= '0' && current <= '9') X { X for (n = 0; n < TITEMS; n++) X if (current == buttons[n].value) break ; X shift = char_val(buttons[n].value) ; X temp = ibool(convert_display()) ; X switch (pending) X { X case '<' : temp = temp << shift ; X break ; X case '>' : temp = temp >> shift ; X } X STRCPY(display, make_number(setbool(temp))) ; X disp_val = last_input = convert_display() ; X } X} X X Xdo_sto_rcl() /* Save/restore value to/from memory register. */ X{ X if (current >= '0' && current <= '9') X switch (pending) X { X case 'r' : disp_val = mem_vals[char_val(current)] ; X break ; X case 's' : switch (pending_op) X { X case '+' : mem_vals[char_val(current)] += disp_val ; X break ; X case '-' : mem_vals[char_val(current)] -= disp_val ; X break ; X case 'x' : mem_vals[char_val(current)] *= disp_val ; X break ; X case '/' : mem_vals[char_val(current)] /= disp_val ; X break ; X case '=' : mem_vals[char_val(current)] = disp_val ; X } X make_registers() ; X } X else if (current == '+' || current == '-' || X current == 'x' || current == '/') pending_op = current ; X} X X Xdo_trig() /* Perform all trigonometric functions. */ X{ X double temp ; X X if (!inverse) X { X if (ttype == DEG) temp = disp_val * M_PI / 180.0 ; X else if (ttype == GRAD) temp = disp_val * M_PI / 200.0 ; X else temp = disp_val ; X X if (!hyperbolic) X switch (current) X { X case CCTRL('c') : tresults[(int) RAD] = cos(temp) ; /* cos */ X break ; X case CCTRL('s') : tresults[(int) RAD] = sin(temp) ; /* sin */ X break ; X case CCTRL('t') : tresults[(int) RAD] = tan(temp) ; /* tan */ X } X else X switch (current) X { X case CCTRL('c') : tresults[(int) RAD] = cosh(temp) ; /* cosh */ X break ; X case CCTRL('s') : tresults[(int) RAD] = sinh(temp) ; /* sinh */ X break ; X case CCTRL('t') : tresults[(int) RAD] = tanh(temp) ; /* tanh */ X } X X tresults[(int) DEG] = tresults[(int) RAD] ; X tresults[(int) GRAD] = tresults[(int) RAD] ; X } X else X { X if (!hyperbolic) X switch (current) X { X case CCTRL('c') : disp_val = acos(disp_val) ; /* acos */ X break ; X case CCTRL('s') : disp_val = asin(disp_val) ; /* asin */ SHAR_EOF echo "End of part 2" echo "File functions.c is continued in part 3" echo "3" > s2_seq_.tmp exit 0