[comp.sources.misc] Calctool v1.4.

richb@sunk.oz.AU (Rich Burridge) (10/07/87)

#! /bin/sh
# this is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh to create the files:
#	README
#	Makefile
#	calctool.c
#	functions.c
#	calctool.h
#	patchlevel.h
#	button.icon
#	calctool.icon
#	help.cursor
#	calctool.help
# This archive created: Mon Oct  5 13:20:46 EST 1987
#
#
export PATH; PATH=/bin:$PATH
#
if [ -f README ]
then
echo shar: will not over-write existing file README
else
echo shar: extracting 'README',     2017 characters
cat > README <<'Funky_Stuff'

calctool  -  README  -  2nd September 1987.

This is V1.4 of a simple desktop calculator for the Sun workstation.
Some of it's features include:

 (1) You can GET and PUT the calculator display.
 (2) Every calculator button has an equivalent key press.
 (3) Built in help, press HLP followed by another selection.
 (4) Normal arithmetic + - x / with constants.
 (6) Logical operations AND OR XOR XNOR and NOT.
 (7) Results can be displayed (and calculated) in binary, octal,
     decimal and hexidecimal.
 (8) The result can be shifted multiple places to the left and right.
 (9) Fractional precision can be 0 to 9 places.
(10) There are ten memory registers for storing and retrieving numbers.
(11) A backspace key to remove last character of the display. Note
     that this loses internal numeric accuracy as the number is
     recalculated from the display value.

Thanks to Ed Falk at Sun Microsystems (Mountain View) for some of the
basic algorithms used.

Thanks to Paul Czarnecki for the fix to the binary display problem.

Thanks to Rich Baughman at the Consumer Financial Institute in Newton
MA, for the following features:

(1) An alternate display for the button values (using the right mouse button
    as the display toggle) that shows the keyboard equivalent input character.

(2) A memory register display screen that shows all the registers in the
    calculator (using the middle mouse button as the display toggle).
    This is helpful when trying to remember what values are stored in those
    registers.

You can now change where the program reads the helpfile information from,
via the -h command line option. 
 
Suggestions for furthur improvement would be most welcome plus bugs,
comments and flames to me.

Regards Rich.

Rich Burridge,            JANET richb%sunk.oz@uk.ac.ucl.cs
ACSnet  richb@sunk.oz     UUCP {seismo,hplabs,ukc}!munnari!sunk.oz!richb
PHONE: +61 3 811 9927     ARPAnet richb%sunk.oz@seismo.css.gov
MAIL: Sun Microsystems, 123 Camberwell Rd, Hawthorn, VICTORIA 3122, AUST
Funky_Stuff
len=`wc -c < README`
if [ $len !=     2017 ] ; then
echo error: README was $len bytes long, should have been     2017
fi
fi # end of overwriting check
if [ -f Makefile ]
then
echo shar: will not over-write existing file Makefile
else
echo shar: extracting 'Makefile',     1191 characters
cat > Makefile <<'Funky_Stuff'
#
#  Makefile for calctool, a simple calculator.
#
#  Copyright (c) Rich Burridge - September 1987.
#                Sun Microsystems, Australia - All rights reserved.
#
#  Includes code and ideas from:
#                Rich Baughman, Consumer Financial Institute, Newton, MA
#
#  Version 1.4.
#
#  No responsibility is taken for any errors inherent either in the comments
#  or the code of this program, but if reported to me then an attempt will
#  be made to fix them.
#

BINARIES      = calctool
BINDIR        = .
CFLAGS        = -g
LDFLAGS       = -g
OBJS          = calctool.o functions.o
SRCS          = calctool.c functions.c
HDRS          = calctool.h
IMAGES        = button.icon calctool.icon help.cursor
LIBS          = -lm -lsuntool -lsunwindow -lpixrect

all:            $(BINARIES)

release:        $(BINARIES)
		strip $(BINARIES)

backup:
		cp calctool.h calctool.h~
		cp calctool.c calctool.c~
		cp calctool.help calctool.help~
		cp functions.c functions.c~

clean:
		rm -f *.o core

lint:
		lint $(SPECIAL) $(SRCS) $(LIBS)

calctool:       $(OBJS)
		cc $(LDFLAGS) -o calctool $(OBJS) $(LIBS)

calctool.o:     calctool.c $(HDRS) $(IMAGES)
functions.o:    functions.c $(HDRS)
Funky_Stuff
len=`wc -c < Makefile`
if [ $len !=     1191 ] ; then
echo error: Makefile was $len bytes long, should have been     1191
fi
fi # end of overwriting check
if [ -f calctool.c ]
then
echo shar: will not over-write existing file calctool.c
else
echo shar: extracting 'calctool.c',    18907 characters
cat > calctool.c <<'Funky_Stuff'

/*  calctool.c
 *
 *  This program looks and acts like a simple calculator.
 *
 *  Copyright (c) Rich Burridge - September 1987.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *  Includes ideas and code from:
 *                Rich Baughman, Consumer Financial Institute, Newton, MA
 *
 *  Version 1.4.
 *
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if
 *  reported to me then an attempt will be made to fix them.
 */

#include "patchlevel.h"
#include "calctool.h"

void canvas_proc() ;
Panel_setting panel_proc() ;

Canvas canvas, rcanvas ;
Cursor main_cursor ;
Event event ;
Frame frame, rframe ;
Icon calctool_icon ;
Panel panel ;
Panel_item base_item, display_item ;
Pixfont *sfont, *nfont ;
Pixwin *cpw, *rcpw ;

short help_cursor_array[16] = {
#include "help.cursor"
} ;
mpr_static(help_cursor_pr,16,16,1,help_cursor_array) ;
struct cursor help_cursor =
         { 0, 0, PIX_SRC | PIX_DST, &help_cursor_pr } ;

short button_image[] = {
#include "button.icon"
} ;
mpr_static(button_pr,64,64,1,button_image) ;

short icon_image[] = {
#include "calctool.icon"
} ;
mpr_static(icon_pixrect,64,64,1,icon_image) ;

double powers[11][4] = {
         {    1.0,          1.0,           1.0,             1.0 },
         {    2.0,          8.0,          10.0,            16.0 },
         {    4.0,         64.0,         100.0,           256.0 },
         {    8.0,        512.0,        1000.0,          4096.0 },
         {   16.0,       4096.0,       10000.0,         65536.0 },
         {   32.0,      32768.0,      100000.0,       1048576.0 },
         {   64.0,     262144.0,     1000000.0,      16777216.0 },
         {  128.0,    2097152.0,    10000000.0,     268435456.0 },
         {  256.0,   16777216.0,   100000000.0,    4294967296.0 },
         {  512.0,  134217728.0,  1000000000.0,   68719476736.0 },
         { 1024.0, 1073741824.0, 10000000000.0, 1099511627776.0 }
} ;

/* Length of display in characters for each base. */
int disp_length[4] = {32, 15, 12, 12} ;

double disp_val ;             /* Value of the current display. */
double last_input ;           /* Previous number input by user. */
double mem_vals[MAXREGS] ;    /* Memory register values. */
double result ;               /* Current calculator total value. */

FILE *hfd ;             /* File descriptor for help information. */

int accuracy ;          /* Number of digits precision (Max 9). */
int base ;              /* Current base: BIN, OCT, DEC or HEX. */
int column ;            /* Column number of key pressed. */
int error ;             /* Indicates some kind of display error. */
int n ;                 /* Index into buttons array structure. */
int new_input ;         /* New number input since last op. */
int nohelp ;            /* Indicates if a help file was found. */
int pointed ;           /* Whether a decimal point has been given. */
int row ;               /* Row number of key pressed. */
int rstate ;            /* Indicates if memory register frame is displayed. */
int toclear ;           /* Indicates if display should be cleared. */
int tstate ;            /* Indicates current button set being displayed. */

/* Routines obeyed by mouse button or character presses. */
do_accuracy(), do_base(), do_calculation(), do_clear() ;
do_close(), do_delete(), do_help(), do_memory(), do_not() ;
do_number(), do_point(), do_quit(), do_shift(), do_sqrt() ;

char c ;                /* Current character typed by the user. */
char cur_op ;           /* Current arithmetic operation. */
char cur_value ;        /* Current button or character pressed. */
char old_cal_value ;    /* Previous calculation operator. */

struct button buttons[TOTAL_ITEMS] = {         /* Calculator button values. */
         { "<<",  do_shift,       '<' },       /* Row 1. */
         { "BIN", do_base,        'B' },
         { "OCT", do_base,        'O' },
         { "DEC", do_base,        'D' },
         { "HEX", do_base,        'H' },
         { ">>",  do_shift,       '>' },

         { "STO", do_memory,      's' },       /* Row 2. */
         { "RCL", do_memory,      'r' },
         { " D ", do_number,      'd' },
         { " E ", do_number,      'e' },
         { " F ", do_number,      'f' },
         { "CLR", do_clear,       '\177' },

         { "NOT", do_not,         '~' },       /* Row 3. */
         { "SQR", do_sqrt,        'S' },
         { " A ", do_number,      'a' },
         { " B ", do_number,      'b' },
         { " C ", do_number,      'c' },
         { "BSP", do_delete,      '\010' },

         { "AND", do_calculation, '&' },       /* Row 4. */
         { "OR",  do_calculation, '|' },
         { " 7 ", do_number,      '7' },
         { " 8 ", do_number,      '8' },
         { " 9 ", do_number,      '9' },
         { " X ", do_calculation, 'x' },

         { "XOR", do_calculation, '^' },       /* Row 5. */
         { "XNR", do_calculation, 'n' },
         { " 4 ", do_number,      '4' },
         { " 5 ", do_number,      '5' },
         { " 6 ", do_number,      '6' },
         { " / ", do_calculation, '/' },

         { "ACC", do_accuracy,    'A' },       /* Row 6. */
         { "HLP", do_help,        '?' },
         { " 1 ", do_number,      '1' },
         { " 2 ", do_number,      '2' },
         { " 3 ", do_number,      '3' },
         { " - ", do_calculation, '-' },

         { "OFF", do_close,       '\033' },    /* Row 7. */
         { "END", do_quit,        'q' },
         { " 0 ", do_number,      '0' },
         { " . ", do_point,       '.' },
         { " = ", do_calculation, '=' },
         { " + ", do_calculation, '+' },

         { "   ", do_calculation, 'X' },        /* Extra useful definitions. */
         { "   ", do_calculation, '*' },
         { "   ", do_calculation, '\015' },
         { "   ", do_quit,        'Q' },
         { "   ", do_calculation, 'N' },
} ;

char display[MAXLINE] ;             /* Current calculator display. */
char helpname[MAXLINE] ;            /* Filename for help file. */
char progname[MAXLINE] ;            /* Name of this program. */


main(argc,argv)
int argc ;
char *argv[] ;

{
  STRCPY(progname,argv[0]) ;        /* Save this programs name. */
  get_options(argc,argv) ;          /* Get command line arguments. */
  nohelp = 0 ;
  if ((hfd = fopen(helpname,"r")) == NULL)
    {
      FPRINTF(stderr,"Help file %s not found\r\n",HELPNAME) ;
      nohelp = 1 ;
    }

  sfont = pf_open(SMALLFONT) ;      /* Open small point font. */
  nfont = pf_open(NORMALFONT) ;     /* Open normal sized font. */
  calctool_icon = icon_create(ICON_WIDTH,42,
                              ICON_IMAGE,&icon_pixrect,
                              0) ;

  frame = window_create((Window) 0, FRAME,
                        FRAME_ICON, calctool_icon,
                        FRAME_SHOW_LABEL, FALSE,
                        FRAME_SUBWINDOWS_ADJUSTABLE, FALSE,
                        FRAME_NO_CONFIRM, TRUE,
                        WIN_TOP_MARGIN, DISPLAY,
                        WIN_ROW_HEIGHT, BUTTON_HEIGHT,
                        WIN_COLUMN_WIDTH, BUTTON_WIDTH,
                        WIN_ROWS, BUTTON_ROWS,
                        WIN_COLUMNS, BUTTON_COLS,
                        FRAME_ARGS, argc,argv,
                        0) ;
  rframe = window_create(frame, FRAME,
                         FRAME_SHOW_LABEL, FALSE,
                         FRAME_NO_CONFIRM, TRUE,
                         WIN_WIDTH,TOTAL_WIDTH+60,
                         WIN_HEIGHT,TOTAL_HEIGHT+10,
                         WIN_FONT,nfont,
                         WIN_Y,(int) window_get(frame, WIN_Y) + DISPLAY + 5,
                         WIN_X,(int) window_get(frame, WIN_X) + TOTAL_WIDTH + 15,
                         0) ;

  panel = window_create(frame, PANEL,
                        WIN_CONSUME_KBD_EVENTS, WIN_ASCII_EVENTS, 0,
                        WIN_HEIGHT, DISPLAY,
                        0) ;
  rcanvas = window_create(rframe,CANVAS,0) ;

  canvas = window_create(frame,CANVAS,
                         WIN_BELOW,panel,
                         WIN_WIDTH,TOTAL_WIDTH,
                         WIN_HEIGHT,TOTAL_HEIGHT,
                         WIN_FONT,nfont,
                         WIN_EVENT_PROC,canvas_proc,
                         0) ;
  WINDOW_SET(canvas,WIN_CONSUME_KBD_EVENT,WIN_ASCII_EVENTS,0) ;

  display_item = panel_create_item(panel,PANEL_TEXT,
                                   PANEL_VALUE_Y,DISPLAY-25,
                                   PANEL_NOTIFY_LEVEL, PANEL_ALL,
                                   PANEL_ACCEPT_KEYSTROKE, 1,
                                   PANEL_NOTIFY_PROC, panel_proc,
                                   PANEL_VALUE_FONT,nfont,
                                   0) ;
  base_item = panel_create_item(panel,PANEL_MESSAGE,
                                PANEL_LABEL_X,10,
                                PANEL_LABEL_Y,DISPLAY-10,
                                PANEL_LABEL_FONT,sfont,
                                PANEL_LABEL_STRING,"",
                                0) ;
  cpw = canvas_pixwin(canvas) ;
  rcpw = canvas_pixwin(rcanvas) ;
  main_cursor = window_get(canvas,WIN_CURSOR) ;

  rstate = 0 ;                /* No memory register frame display initially. */
  tstate = 0 ;                /* Button values displayed first. */
  base = DEC ;                /* Initial base. */
  accuracy = 2 ;              /* Initial accuracy. */
  do_clear() ;                /* Initialise and clear display. */

  make_registers() ;          /* Calculate memory register frame values. */
  make_canvas(0) ;            /* Draw the calculators buttons. */
  window_fit(frame) ;
  window_main_loop(frame) ;
  exit(0) ;
}


/*ARGSUSED*/
Panel_setting
panel_proc(item,event)
Panel_item item ;
Event *event ;

{
  int chr ;

  chr = event_id(event) ;
  for (n = 0; n < TOTAL_ITEMS; n++)
    {
      if (chr == buttons[n].value)
        {
          PANEL_SET(item,PANEL_NOTIFY_LEVEL,PANEL_NONE,0) ;
          process_item(n) ;
          PANEL_SET(item,PANEL_NOTIFY_LEVEL,PANEL_ALL,0) ;
          return ;
        }
    }
}


/*ARGSUSED*/
static void
canvas_proc(win,event,arg)
Canvas  win ;
Event *event ;
caddr_t arg ;

{
  int column,row ;

  if (event_is_button(event) && event_is_up(event))
    {
      switch (event_id(event))
        {
          case MS_LEFT   : column = event_x(event) / (BUTTON_WIDTH + BUTTON_GAP) ;
                           row = event_y(event) / (BUTTON_HEIGHT + BUTTON_GAP) ;
                           n = row*BUTTON_COLS+column ;
                           break ;
          case MS_MIDDLE : toggle_reg_canvas() ;
                           return ;
          case MS_RIGHT  : make_canvas(1) ;
                           return ;
        }
    }
  else if (event_is_ascii(event))
    {
      for (n = 0; n < TOTAL_ITEMS; n++)
        if (event_id(event) == buttons[n].value) break ;
      if (n == TOTAL_ITEMS) return ;
    }
  else return ;

  process_item(n) ;
}

    
process_item(n)
int n ;

{
  cur_value = buttons[n].value ;

  if (cur_value == 'X') cur_value = 'x' ;       /* Reassign "extra" values. */
  if (cur_value == '*') cur_value = 'x' ;
  if (cur_value == '\015') cur_value = '=' ;
  if (cur_value == 'Q') cur_value = 'q' ;
  if (cur_value == 'N') cur_value = 'n' ;

  if (error && cur_value != '\177') return ;    /* If error, must clear first. */

  (*buttons[n].func)() ;
}


char_val(chr)
char chr ;
 
{
       if (chr >= '0' && chr <= '9') return(chr - '0') ;
  else if (chr >= 'a' && chr <= 'f') return(chr - 'a' + 10) ;
  else return(-1) ;
}


clear_display()

{
  int i ;

  pointed = 0 ;
  toclear = 1 ;
  STRCPY(display,"0.") ;
  for (i = 0; i < accuracy; i++)
    STRNCAT(display,"0",1) ;
  display_result(display) ;
  disp_val = 0.0 ;
}


double
convert_display()    /* Convert input string into a double. */
 
{
  static int basevals[4] = {2, 8, 10, 16} ;
  int i,inum ;
  double val ;
  char *optr ;

  val = 0.0 ;
  optr = display ;
  while ((inum = char_val(*optr)) >= 0)
    {
      val = val * basevals[base] + inum ;
      *optr++ ;
    }
      
  if (*optr == '.')
    for (i = 1; (inum = char_val(*++optr)) >= 0; i++)
      val += inum / powers[i][base] ;
  return(val) ;
}
 
 
display_base(base)
int base ;

{
  char base_str[MAXLINE] ;

  switch (base)
    {
      case BIN : STRCPY(base_str,"BIN") ;
                 break ;
      case OCT : STRCPY(base_str,"OCT") ;
                 break ;
      case DEC : STRCPY(base_str,"") ;
                 break ;
      case HEX : STRCPY(base_str,"HEX") ;
    }
  PANEL_SET(base_item,PANEL_LABEL_STRING,base_str,0) ;
}


display_result(display)       /* Output result to calculator display. */
char display[MAXLINE] ;

{
  PANEL_SET(display_item,PANEL_VALUE_X,20+(MAX_DIGITS - strlen(display))*7,
                         PANEL_VALUE,display,
                         0) ;
}


get_next_value()              /* Get next key or mouse button press. */

{
  int column,found,n,row ;
   
  found = 0 ;
  while (!found)
    {
      WINDOW_READ_EVENT(canvas,&event) ;
      if (event_is_button(&event) && event_is_up(&event))
        {
          column = event_x(&event) / (BUTTON_WIDTH + BUTTON_GAP) ;
          row = event_y(&event) / (BUTTON_HEIGHT + BUTTON_GAP) ;
          n = row*BUTTON_COLS+column ;
          if (n < TOTAL_ITEMS) found = 1 ;
        }
      else if (event_is_ascii(&event))
        {
          c = event_id(&event) ;
          for (n = 0; n < TOTAL_ITEMS; n++)
            if (c == buttons[n].value)
              {
                found = 1 ;
                break ;
              }
        }
    }
  return(n) ;
}
 
 
get_options(argc,argv)        /* Extract command line options. */
int argc ;
char *argv[] ;

{
  char *arg ;
  char *p ;      /* Pointer to string following argument flag. */

  STRCPY(helpname,HELPNAME) ;    /* Default help filename. */
  while (argc > 1 && (arg = argv[1])[0] == '-')
    {
      p = arg + 2 ;
      switch (arg[1])
        {
          case 'h' : STRCPY(helpname,p) ;      /* Get new help filename. */
                     break ;
          case 'v' : FPRINTF(stderr,"%s version 1.4.%1d\n",progname,PATCHLEVEL) ;
                     break ;
          case '?' : FPRINTF(stderr,"USAGE %s [-hhelpfile] [-v] [-?]\n",progname) ;
                     exit(1) ;
        }
      argc-- ;
      argv++ ;
    }
}


initialise()

{
  error = 0 ;                 /* Currently no display error. */
  cur_op = '?' ;              /* No arithmetic operator defined yet. */
  old_cal_value = '?' ;
  result = 0.0 ;              /* No previous result yet. */
  last_input = 0.0 ;
}


make_canvas(toggle)           /* Draw the calculators buttons. */
int toggle ;                  /* Should we toggle the display of buttons. */
{
  int n,x ;
  char pstr[10] ;

  if (toggle) tstate = !tstate ;

/*  Each call alternates button display, between display string, and
 *  single-char input character.
 */

  pw_writebackground(cpw,0,0,TOTAL_WIDTH,TOTAL_HEIGHT,PIX_CLR) ;
  for (row = 0; row < BUTTON_ROWS; row++)
    for (column = 0; column < BUTTON_COLS; column++)
      {
        n = row * BUTTON_COLS + column ;
        if (tstate)
          {
            switch (buttons[n].value)
              {
                case '\010' : STRCPY(pstr,"BSP") ;
                              break ;
                case '\033' : STRCPY(pstr,"ESC") ;
                              break ;
                case '\177' : STRCPY(pstr,"DEL") ;
                              break ;
                default     : SPRINTF(pstr," %c ",buttons[n].value) ;
              }
          }
        else STRCPY(pstr,buttons[n].str) ;

        pw_write(cpw,column*BUTTON_WIDTH+BUTTON_BORDER+(column*BUTTON_GAP),
                     row*BUTTON_HEIGHT+BUTTON_BORDER+(row*BUTTON_GAP),
                     BUTTON_WIDTH,BUTTON_HEIGHT,PIX_SRC,&button_pr,0,0) ;
        x = (strlen(pstr) == 3) ? 8 : 11 ;
        pw_text(cpw,column*BUTTON_WIDTH+BUTTON_BORDER+(column*BUTTON_GAP)+x,
                          row*BUTTON_HEIGHT+BUTTON_BORDER+(row*BUTTON_GAP)+14,
                          PIX_SRC | PIX_DST,nfont,pstr) ;
      }
}


make_display(display)    /* Output calculators display - right justified. */
char display[MAXLINE] ;

{
  PANEL_SET(display_item,PANEL_VALUE_X,20+(MAX_DIGITS - strlen(display))*7,
                         PANEL_VALUE,display,
                         0) ;
}


char *
make_number(number)        /* Convert display value to current base. */
double number ;            /* Value to convert. */

{
  char *optr,display[MAXLINE] ;
  double val ;
  int cmax ;               /* Maximum number of characters to display. */
  int ndig ;               /* Total number of digits to generate. */
  int ddig ;               /* Number of digits to left of . */
  int dval ;
  static char digits[] = "0123456789abcdef" ;

  if (isinf(number) || isnan(number))
    {
      STRCPY(display,"Error") ;
      error = 1 ;
      return(display) ;
    }

  cmax = disp_length[base] ;
  optr = display ;
  val = fabs(number) ;
  if (number < 0.0) *optr++ = '-' ;
  val += .5 / powers[accuracy][base] ;

  if (val < 1.0)
    {
      ddig = 0 ;
      *optr++ = '0' ;
      cmax-- ;
    }
  else
    {
      for (ddig = 0; val >= 1.0; ddig++)
        val /= powers[1][base] ;
    }

  if ((ndig = ddig + accuracy) > cmax)
    {
      if (ddig > cmax)
        {
          STRCPY(display,"Overflow") ;
          error = 1 ;
          return(display) ;
        }
      else
        {
          STRCPY(display,"Reducing precision") ;
          display_result(display) ;
          sleep(1) ;
          bzero(display,MAXLINE) ;
          accuracy = cmax - ddig ;
          if (accuracy < 0) accuracy = 0 ;
          ndig = ddig + accuracy ;
        }
    }

  while (ndig-- > 0)
    {
      if (ddig-- == 0) *optr++ = '.' ;
      val *= powers[1][base] ;
      dval = val ;
      *optr++ = digits[dval] ;
      val -= (int) val ;
    }
 *optr++ = '\0' ;
  toclear = 1 ;
  pointed = 0 ;
  return(display) ;
}


make_registers()           /* Calculate memory register frame values. */

{
  char line[MAXLINE] ;     /* Current memory register line. */
  int n ;
  int height,width ;       /* Dimensions of this frame. */

  height = (int) window_get(rframe,WIN_HEIGHT) ;
  width = (int) window_get(rframe,WIN_WIDTH) ;
  pw_writebackground(rcpw,0,0,width,height,PIX_CLR) ;
  pw_text(rcpw,15,20,PIX_SRC,nfont,"MEMORY REGISTERS") ;
  for (n = 0; n < MAXREGS; n++)
    {
      SPRINTF(line,"%1d   ",n) ;
      STRCAT(line,make_number(mem_vals[n])) ;
      pw_text(rcpw,15,40+15*n,PIX_SRC,nfont,line) ;
    }
}


make_text(x,y,line)        /* Output a line of text. */
int x,y ;
char line[MAXLINE] ;

{
  pw_text(cpw,x,y,PIX_SRC,nfont,line) ;
}


toggle_reg_canvas()

{
  rstate = !rstate ;
  if (rstate) WINDOW_SET(rframe, WIN_SHOW, TRUE, 0) ;
  else WINDOW_SET(rframe, WIN_SHOW, FALSE, 0) ;
}
Funky_Stuff
len=`wc -c < calctool.c`
if [ $len !=    18907 ] ; then
echo error: calctool.c was $len bytes long, should have been    18907
fi
fi # end of overwriting check
if [ -f functions.c ]
then
echo shar: will not over-write existing file functions.c
else
echo shar: extracting 'functions.c',     9184 characters
cat > functions.c <<'Funky_Stuff'

/*  functions.c
 *
 *  This file contains the seperate functions used whenever a calculator
 *  button is pressed.
 *
 *  Copyright (c) Rich Burridge - September 1987.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *  Includes ideas and code from:
 *                Rich Baughman, Consumer Financial Institute, Newton, MA
 *
 *  Version 1.4.
 *
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if
 *  reported to me then an attempt will be made to fix them.
 */

#include "calctool.h"

double setbool() ;

extern char *make_number() ;
extern double convert_display() ;

extern Canvas canvas ;
extern Cursor main_cursor ;
extern Event event ;
extern Frame frame, rframe ;
extern Panel_item base_item ;
extern Pixwin *cpw ;
extern struct cursor help_cursor ;

extern FILE *hfd ;                /* File descriptor for help information. */
extern struct button buttons[] ;  /* Calculator button values. */

/* Length of display in characters for each base. */
extern int disp_length[] ;

extern double disp_val ;          /* Value of the current display. */
extern double last_input ;        /* Previous number input by user. */
extern double mem_vals[] ;        /* Memory register values. */
extern double result ;            /* Current calculator total value. */

extern int accuracy ;             /* Number of digits precision (Max 9). */
extern int base ;                 /* Current base: BIN, OCT, DEC or HEX. */
extern int new_input ;            /* New number input since last op. */
extern int nohelp ;               /* Indicates if a help file was found. */
extern int pointed ;              /* Whether a decimal point has been given. */
extern int toclear ;              /* Indicates if display should be cleared. */

extern char cur_op ;              /* Current arithmetic operation. */
extern char cur_value ;           /* Current button or character pressed. */
extern char old_cal_value ;       /* Previous calculation operator. */
extern char display[MAXLINE] ;    /* Current calculator display. */


do_accuracy()       /* Get value for number of digits accuracy. */

{
  int n,valid ;

  valid = 0 ;
  while (!valid)
    {
      n = get_next_value() ;
      if (buttons[n].value >= '0' && buttons[n].value <= '9')
        {
          accuracy = char_val(buttons[n].value) ;
          valid = 1 ;
        }
    }
  STRCPY(display,make_number(disp_val)) ;
  display_result(display) ;
  make_registers() ;
}


do_base()    /* Change the current base setting. */

{
  switch (cur_value)
    {
      case 'B' : base = BIN ;
                 break ;
      case 'O' : base = OCT ;
                 break ;
      case 'D' : base = DEC ;
                 break ;
      case 'H' : base = HEX ;
    }
  display_base(base) ;
  STRCPY(display,make_number(disp_val)) ;   /* Convert display value to current base. */
  display_result(display) ;
  make_registers() ;
}


do_calculation()      /* Perform arithmetic calculation and display result. */

{
  int isboolean ;
  BOOLEAN temp ;

  if (cur_value == '=' && old_cal_value == '=')
    if (new_input) result = last_input ;
    else disp_val = last_input ;

  if (cur_value != '=' && old_cal_value == '=') cur_op = '?' ;
  isboolean = 0 ;

  switch (cur_op)
    {
      case '?'    : result = disp_val ;          /* Undefined. */
                    break ;
      case '+'    : result += disp_val ;         /* Addition. */
                    break ;
      case '-'    : result -= disp_val ;         /* Subtraction. */
                    break ;
      case 'x'    : result *= disp_val ;         /* Multiplication. */
                    break ;
      case '/'    : result /= disp_val ;         /* Division. */
                    break ;

      case '&'    : temp = (BOOLEAN) result & (BOOLEAN) disp_val ;   /* AND. */
                    isboolean = 1 ;
                    break ;
      case '|'    : temp = (BOOLEAN) result | (BOOLEAN) disp_val ;   /* OR. */
                    isboolean = 1 ;
                    break ;
      case '^'    : temp = (BOOLEAN) result ^ (BOOLEAN) disp_val ;   /* XOR. */
                    isboolean = 1 ;
                    break ;
      case 'n'    : temp = (BOOLEAN) result ^ (BOOLEAN) disp_val ;   /* XNOR. */
                    temp = ~((BOOLEAN) temp) ;
                    isboolean = 1 ;
                    break ;
      case '='    : break ;                                        /* Equals. */
    }

  if (isboolean) result = setbool(temp) ;
  STRCPY(display,make_number(result)) ;
  display_result(display) ;
  if (!(cur_value == '=' && old_cal_value == '=')) last_input = disp_val ;

  disp_val = result ;
  if (cur_value != '=') cur_op = cur_value ;
  old_cal_value = cur_value ;
  new_input = 0 ;
}


do_clear()       /* Clear the calculator display and re-initialise. */

{
  clear_display() ;
  initialise() ;
}


do_close()       /* Close the window to its iconic form. */

{
  if ((int) window_get(rframe, WIN_SHOW) == TRUE)
    toggle_reg_canvas() ;
  WINDOW_SET(frame,FRAME_CLOSED,TRUE,0) ;
}


do_delete()     /* Remove the last numeric character typed. */

{
  if (strlen(display)) display[strlen(display)-1] = '\0' ;
  display_result(display) ;
  disp_val = convert_display() ;    /* Convert input to a number. */
}

do_help()

{
  char help_str[MAXLINE],nextline[MAXLINE],*p ;
  int n,y ;

  PANEL_SET(base_item,PANEL_LABEL_STRING,"HLP",0) ;
  n = get_next_value() ;
  display_base(base) ;

  WINDOW_SET(canvas,WIN_CURSOR,&help_cursor,0) ;
  pw_writebackground(cpw,0,0,TOTAL_WIDTH,TOTAL_HEIGHT,PIX_CLR) ;
  if (nohelp) make_text(20,20,"No help file found.") ;
  else
    { 
      SPRINTF(help_str,"%%%s%%\n",buttons[n].str) ;
      rewind(hfd) ;
      while (p = fgets(nextline,BUFSIZ,hfd))
        if (*p == '%' && EQUAL(p,help_str)) break ;
      y = 15 ;
      for (;;)
        {
          FGETS(nextline,BUFSIZ,hfd) ;
          if (EQUAL(nextline,"%%\n")) break ;
          nextline[strlen(nextline)-1] = '\0' ;
          make_text(5,y,nextline) ;
          y += 15 ;
        }
    }

  make_text(5,y+25,DEF_CONT_MSG) ;
  for (;;)
    {
      WINDOW_READ_EVENT(canvas,&event) ;
      if ((event_is_up(&event) && event_is_button(&event)) ||
          (event_is_ascii(&event) && event_id(&event))) break ;
    }
  make_canvas(0) ;
  WINDOW_SET(canvas,WIN_CURSOR,main_cursor,0) ;
}


do_memory()        /* Store or retrieve number from memory location. */

{
  int n,valid ;

  valid = 0 ;
  while (!valid)
    {
      n = get_next_value() ;
      if (buttons[n].value >= '0' && buttons[n].value <= '9')
        {
          switch (cur_value)
            {
              case 'r' : disp_val = mem_vals[char_val(buttons[n].value)] ;
                         break ;
              case 's' : mem_vals[char_val(buttons[n].value)] = disp_val ;
                         make_registers() ;
            }
          valid = 1 ;
        }
    }    
  STRCPY(display,make_number(disp_val)) ;
  display_result(display) ;
}


do_not()         /* Do logical NOT operation on current display value. */
 
{
  disp_val = setbool(~((BOOLEAN) disp_val)) ;
  STRCPY(display,make_number(disp_val)) ;
  display_result(display) ;
}


do_number()

{
  int n ;
  static int maxvals[4] = {1, 7, 9, 15} ;

  n = cur_value - '0' ;
  if (base == HEX && cur_value >= 'a' && cur_value <= 'f')
    n = cur_value - 'a' + 10 ;
  if (n > maxvals[base]) return ;

  if (toclear)
    {
      SPRINTF(display,"%c",cur_value) ;
      toclear = 0 ;
    }
  else if (strlen(display) < disp_length[base])
    STRNCAT(display,&cur_value,1) ;
  make_display(display) ;
  disp_val = convert_display() ;    /* Convert input to a number. */
  new_input = 1 ;
}


do_point()       /* Handle numeric point. */

{
  if (!pointed)
    {
      if (toclear)
        {
          STRCPY(display,".") ;
          toclear = 0 ;
        }
      else if (strlen(display) < disp_length[base])
        STRNCAT(display,".",1) ;
      pointed = 1 ;
    }
  make_display(display) ;
  disp_val = convert_display() ;    /* Convert input to a number. */
}


do_quit()        /* Terminate the program. */

{
  WINDOW_DESTROY(frame) ;
  WINDOW_DESTROY(rframe) ;
}


do_shift()       /* Shift the display value to the left or the right. */

{
  int n,shift,valid ;
  BOOLEAN temp ;
 
  valid = 0 ;
  while (!valid)
    {
      n = get_next_value() ;
      if (buttons[n].value >= '0' && buttons[n].value <= '9')
        {
          shift = char_val(buttons[n].value) ;
          valid = 1 ;
        }
    }
  temp = (BOOLEAN) convert_display() ;
  switch (cur_value)
    {
      case '<' : temp = temp << shift ;
                 break ;
      case '>' : temp = temp >> shift ;
    }
  STRCPY(display,make_number(setbool(temp))) ;
  display_result(display) ;
  disp_val = last_input = convert_display() ;
}


do_sqrt()        /* Square root. */

{
  disp_val = sqrt(disp_val) ;
  STRCPY(display,make_number(disp_val)) ;
  display_result(display) ;
}


double
setbool(p)
BOOLEAN p ;

{
  BOOLEAN q ;
  double val ;

  q = p & 0x80000000 ;
  p &= 0x7fffffff ;
  val = (double) p ;
  if (q) val += 2147483648.0 ;
  return(val) ;
}
Funky_Stuff
len=`wc -c < functions.c`
if [ $len !=     9184 ] ; then
echo error: functions.c was $len bytes long, should have been     9184
fi
fi # end of overwriting check
if [ -f calctool.h ]
then
echo shar: will not over-write existing file calctool.h
else
echo shar: extracting 'calctool.h',     3213 characters
cat > calctool.h <<'Funky_Stuff'

/*  calctool.h
 *
 *  This files contains all the definitions used by the calctool program.
 *
 *  Copyright (c) Rich Burridge - September 1987.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *  Includes ideas and code from:
 *                Rich Baughman, Consumer Financial Institute, Newton, MA
 *
 *  Version 1.4.
 *
 *  No responsibility is taken for any errors or inaccuracies inherent
 *  either to the comments or the code of this program, but if
 *  reported to me then an attempt will be made to fix them.
 */

#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <math.h>

#include <suntool/sunview.h>
#include <suntool/canvas.h>
#include <suntool/panel.h>

char *sprintf() ;

#define  FGETS          (void) fgets     /* To make lint happy. */
#define  FPRINTF        (void) fprintf
#define  IOCTL          (void) ioctl
#define  PANEL_SET      (void) panel_set
#define  READ           (void) read
#define  SPRINTF        (void) sprintf
#define  SSCANF         (void) sscanf
#define  STRCAT         (void) strcat
#define  STRCPY         (void) strcpy
#define  STRNCAT        (void) strncat
#define  STRNCPY            (void) strncpy
#define  WINDOW_DESTROY     (void) window_destroy
#define  WINDOW_READ_EVENT  (void) window_read_event
#define  WINDOW_SET         (void) window_set

#define  SMALLFONT      "/usr/lib/fonts/fixedwidthfonts/screen.r.7"
#define  NORMALFONT     "/usr/lib/fonts/fixedwidthfonts/screen.r.12"

#define  BIN            0                /* Base definitions. */
#define  OCT            1
#define  DEC            2
#define  HEX            3

#define  BUTTON_BORDER  5                /* No of pixels in border. */
#define  BUTTON_COLS    6                /* No of columns of buttons. */
#define  BUTTON_GAP     5                /* No of pixels between buttons. */
#define  BUTTON_HEIGHT  22               /* Number of pixels for height. */
#define  BUTTON_ROWS    7                /* No of rows of buttons. */
#define  BUTTON_WIDTH   36               /* No of pixels for width. */
#define  DEF_CONT_MSG   "Hit any key or button to continue."
#define  DISPLAY        30               /* Calculators numerical display. */

#define  EQUAL          !strcmp          /* For character comparisons. */
#define  EXTRA          5                /* Extra useful character definitions. */
#define  HELPNAME       "calctool.help"
#define  MAX_DIGITS     32               /* Maximum displayable number of digits. */
#define  MAXLINE        80               /* Length of character strings. */
#define  MAXREGS        10               /* Maximum number of memory registers. */
#define  MIN(x,y)       ((x) < (y) ? (x) : (y))
#define  NOBUTTONS      BUTTON_ROWS * BUTTON_COLS
#define  TOTAL_HEIGHT   (BUTTON_ROWS * BUTTON_HEIGHT) + \
                        ((BUTTON_ROWS - 1) * BUTTON_GAP) + (2 * BUTTON_BORDER)
#define  TOTAL_ITEMS    NOBUTTONS + EXTRA    /* Total number of definitions. */
#define  TOTAL_WIDTH    (BUTTON_COLS * BUTTON_WIDTH) + \
                        ((BUTTON_COLS - 1) * BUTTON_GAP) + (2 * BUTTON_BORDER)

typedef  unsigned long  BOOLEAN ;

struct button {
         char *str ;
         int  (*func)() ;
         char value ;
} ;
Funky_Stuff
len=`wc -c < calctool.h`
if [ $len !=     3213 ] ; then
echo error: calctool.h was $len bytes long, should have been     3213
fi
fi # end of overwriting check
if [ -f patchlevel.h ]
then
echo shar: will not over-write existing file patchlevel.h
else
echo shar: extracting 'patchlevel.h',       23 characters
cat > patchlevel.h <<'Funky_Stuff'
#define  PATCHLEVEL  1
Funky_Stuff
len=`wc -c < patchlevel.h`
if [ $len !=       23 ] ; then
echo error: patchlevel.h was $len bytes long, should have been       23
fi
fi # end of overwriting check
if [ -f button.icon ]
then
echo shar: will not over-write existing file button.icon
else
echo shar: extracting 'button.icon',     1933 characters
cat > button.icon <<'Funky_Stuff'
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
 */
	0x1FFF,0xFFFF,0x0000,0x0000,0x3FFF,0xFFFF,0x8000,0x0000,
	0x6000,0x0000,0xC000,0x0000,0xC000,0x0000,0xE000,0x0000,
	0xCFFF,0xFFFF,0x6000,0x0000,0xC800,0x0002,0xE000,0x0000,
	0xC800,0x0003,0x6000,0x0000,0xC800,0x0002,0xE000,0x0000,
	0xC800,0x0003,0x6000,0x0000,0xC800,0x0002,0xE000,0x0000,
	0xC800,0x0003,0x6000,0x0000,0xC800,0x0002,0xE000,0x0000,
	0xC800,0x0003,0x6000,0x0000,0xC800,0x0002,0xE000,0x0000,
	0xC800,0x0003,0x6000,0x0000,0xC800,0x0002,0xE000,0x0000,
	0xC800,0x0003,0x6000,0x0000,0xCFFF,0xFFFE,0xE000,0x0000,
	0xD555,0x5555,0x6000,0x0000,0x6AAA,0xAAAA,0xC000,0x0000,
	0x3FFF,0xFFFF,0x8000,0x0000,0x1FFF,0xFFFF,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
	0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
Funky_Stuff
len=`wc -c < button.icon`
if [ $len !=     1933 ] ; then
echo error: button.icon was $len bytes long, should have been     1933
fi
fi # end of overwriting check
if [ -f calctool.icon ]
then
echo shar: will not over-write existing file calctool.icon
else
echo shar: extracting 'calctool.icon',     1933 characters
cat > calctool.icon <<'Funky_Stuff'
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
 */
	0x1555,0x5555,0x5540,0x0000,0x2AAA,0xAAAA,0xAA80,0x0000,
	0x5555,0x5555,0x5540,0x0000,0xFFFF,0xFFFF,0xFE80,0x0000,
	0x8000,0x0000,0x0340,0x0000,0xBFFF,0xFFFF,0xFA80,0x0000,
	0xA000,0x0000,0x0B40,0x0000,0xA000,0x0000,0x0A80,0x0000,
	0xA600,0x2082,0x0B40,0x0000,0xA900,0x6186,0x0A80,0x0000,
	0xA200,0x2282,0x0B40,0x0000,0xA100,0x23C2,0x0A80,0x0000,
	0xA908,0x2082,0x0B40,0x0000,0xA608,0x7087,0x0A80,0x0000,
	0xA000,0x0000,0x0B40,0x0000,0xA000,0x0000,0x0A80,0x0000,
	0xBFFF,0xFFFF,0xFB40,0x0000,0x8000,0x0000,0x0280,0x0000,
	0x8000,0x0000,0x0340,0x0000,0xBFDF,0xEFF7,0xFA80,0x0000,
	0xA050,0x2814,0x0B40,0x0000,0xAF53,0x2994,0x0A80,0x0000,
	0xA154,0xAA55,0x1340,0x0000,0xA253,0x2A54,0xAA80,0x0000,
	0xA254,0xA9D4,0x4B40,0x0000,0xA454,0xA854,0xAA80,0x0000,
	0xA453,0x2995,0x1B40,0x0000,0xA050,0x2814,0x0A80,0x0000,
	0xBFDF,0xEFF7,0xFB40,0x0000,0x8000,0x0000,0x0280,0x0000,
	0xBFDF,0xEFF7,0xFB40,0x0000,0xA050,0x2814,0x0A80,0x0000,
	0xA257,0xA994,0x2B40,0x0000,0xA654,0x2A14,0x4A80,0x0000,
	0xAA57,0x2B94,0x4B40,0x0000,0xAF50,0xAA54,0x8A80,0x0000,
	0xA254,0xAA54,0x8B40,0x0000,0xA253,0x2995,0x0A80,0x0000,
	0xA050,0x2814,0x0B40,0x0000,0xBFDF,0xEFF7,0xFA80,0x0000,
	0x8000,0x0000,0x0340,0x0000,0xBFDF,0xEFF7,0xFA80,0x0000,
	0xA050,0x2814,0x0B40,0x0000,0xA253,0x2994,0x0A80,0x0000,
	0xA654,0xAA54,0x0B40,0x0000,0xA250,0xA895,0xEA80,0x0000,
	0xA253,0x2854,0x0B40,0x0000,0xA254,0x2A54,0x0A80,0x0000,
	0xA757,0xA994,0x0B40,0x0000,0xA050,0x2814,0x0A80,0x0000,
	0xBFDF,0xEFF7,0xFB40,0x0000,0x8000,0x0000,0x0280,0x0000,
	0xBFDF,0xEFF7,0xFB40,0x0000,0xA050,0x2814,0x0A80,0x0000,
	0xA650,0x2814,0x0B40,0x0000,0xA950,0x2814,0x4A80,0x0000,
	0xAB50,0x2BD4,0x4B40,0x0000,0xAD50,0x2815,0xFA80,0x0000,
	0xA951,0x2BD4,0x4B40,0x0000,0xA651,0x2814,0x4A80,0x0000,
	0xA050,0x2814,0x0B40,0x0000,0xBFDF,0xEFF7,0xFA80,0x0000,
	0x8000,0x0000,0x0300,0x0000,0xFFFF,0xFFFF,0xFE00,0x0000
Funky_Stuff
len=`wc -c < calctool.icon`
if [ $len !=     1933 ] ; then
echo error: calctool.icon was $len bytes long, should have been     1933
fi
fi # end of overwriting check
if [ -f help.cursor ]
then
echo shar: will not over-write existing file help.cursor
else
echo shar: extracting 'help.cursor',      193 characters
cat > help.cursor <<'Funky_Stuff'
/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16
 */
	0xFFFF,0x8001,0xBFFD,0xA1C5,0xA225,0xA225,0xA025,0xA045,
	0xA085,0xA085,0xA005,0xA085,0xA085,0xBFFD,0x8001,0xFFFF
Funky_Stuff
len=`wc -c < help.cursor`
if [ $len !=      193 ] ; then
echo error: help.cursor was $len bytes long, should have been      193
fi
fi # end of overwriting check
if [ -f calctool.help ]
then
echo shar: will not over-write existing file calctool.help
else
echo shar: extracting 'calctool.help',     5668 characters
cat > calctool.help <<'Funky_Stuff'
%<<%
Left shift n                ( < ).

This must be followed by a digit
in the range 0 to 9 to indicate
how many places to shift.
%%

%BIN%
Change base to binary       ( B ).

The display value is shown in
binary. A maximum of 32 digits
are allowed.
%%

%OCT%
Change base to octal        ( O ).

The display value is shown in
octal. A maximum of 15 digits
are allowed.
%%

%DEC%
Change base to decimal      ( D ).

The display value is shown in
decimal. This is the default
base. A maximum of 12 digits
are allowed.
%%

%HEX%
Change base to hexidecimal  ( H ).

The display value is shown in
hexidecimal. A maximum of 12
digits are allowed.
%%

%>>%
Right shift n               ( > ).

This must be followed by a digit
in the range 0 to 9 to indicate
how many places to shift.
%%

%STO%
Store memory register n     ( s ).

This must be followed by a digit
in the range 0 to 9 to indicate
which memory register to store
the current display value in.
%%

%RCL%
Retrieve memory register n  ( r ).

This must be followed by a digit
in the range 0 to 9 to indicate
which memory register to retrieve
the value from.
%%

% D %
Hex D (decimal 13)          ( d ).

This selection is only valid if
the current base is hexidecimal.
%%

% E %
Hex E (decimal 14)          ( e ).

This selection is only valid if
the current base is hexidecimal.
%%

% F %
Hex F (decimal 15)          ( f ).

This selection is only valid if
the current base is hexidecimal.
%%

%CLR%
Clear display          ( DELETE ).

This will clear the value of the
calculators display.
%%

%NOT%
Logical NOT                 ( ~ ).

This operation will perform the
logical NOT operation of the
current value of the calculators
display.
%%

%SQR%
Square root                 ( S ).

This operation will perform a
square root operation on the
current value of the calculator
display.
%%

% A %
Hex A (decimal 10)          ( a ).

This selection is only valid if
the current base is hexidecimal.
%%

% B %
Hex B (decimal 11)          ( b ).

This selection is only valid if
the current base is hexidecimal.
%%

% C %
Hex C (decimal 12)          ( c ).

This selection is only valid if
the current base is hexidecimal.
%%

%BSP%
Erase character     ( BACKSPACE ).

The right most character of the
current calculator display value
is removed, and the value of the
display is recalculated. Note,
internal accuracy is lost with
this operation.
%%

%AND%
Logical AND                 ( & ).

This operation takes the last
number and the next number
entered, and performs a logical
AND operation on them, treating
both numbers as unsigned long
integers.
%%

%OR%
Logical OR                  ( | ).

This operation takes the last
number and the next number
entered, and performs a logical
OR operation on them, treating
both numbers as unsigned long
integers.
%%

% 7 %
Numeric 7                   ( 7 ).

This selection is ignored if
the current base is binary.
%%

% 8 %
Numeric 8                   ( 8 ).

This selection is ignored if
the current base is octal or
binary.
%%

% 9 %
Numeric 9                   ( 9 ).

This selection is ignored if
the current base is octal or
binary.
%%

% X %
Multiplication    ( * or x or X ).

This operation takes the last
number and the next number
entered, and performs an
arithmetic multiplication on
them.
%%

%XOR%
Logical XOR                 ( ^ ).

This operation takes the last
number and the next number
entered, and performs a logical
XOR operation on them, treating
both numbers as unsigned long
integers.
%%

%XNR%
Logical XNOR           ( n or N ).

This operation takes the last
number and the next number
entered, and performs a logical
XNOR operation on them, treating
both numbers as unsigned long
integers.
%%

% 4 %
Numeric 4                   ( 4 ).

This selection is ignored if
the current base is binary.
%%

% 5 %
Numeric 5                   ( 5 ).

This selection is ignored if
the current base is binary.
%%

% 6 %
Numeric 6                   ( 6 ).

This selection is ignored if
the current base is binary.
%%

% / %
Division                    ( / ).

This operation takes the last
number and performs an
arithemetic division by the
next number entered.
%%

%ACC%
Accuracy n                  ( A ).

This must be followed by a digit
in the range 0 to 9 to indicate
how many digits of precision are
to be displayed.
%%

%HLP%
Calctool Help v1.4.         ( ? ).

All calculations performed as
doubles. The display can be used
with the GET and PUT function keys
with other Sunview windows. right
mouse button toggles button display
with keyboard equivalents. Middle
button toggles register display.

For furthur help, select HLP and
another selection.
%%

% 1 %
Numeric 1                   ( 1 ).
%%

% 2 %
Numeric 2                   ( 2 ).

This selection is ignored if
the current base is binary.
%%

% 3 %
Numeric 3                   ( 3 ).

This selection is ignored if
the current base is binary.
%%

% - %
Subtraction                 ( - ).

This operation takes the last
number and performs an
arithemetic subtraction of the
next number entered.
%%

%OFF%
Turn calctool iconic      ( ESC ).

This operation is ignored if
not a Sun Tool.
%%

%END%
Quit calctool          ( q or Q ).

The calctool program is exited.
%%

% 0 %
Numeric 0                   ( 0 ).
%%

% . %
Numeric point               ( . ).

Selecting this starts the
fractional part of the numeric
entry.
%%

% = %
Calculate result  ( = or RETURN ).

The result of the current
calculation is displayed in
the current base.
%%

% + %
Addition                    ( + ).

This operation takes the last
number and the next number
entered, and performs an
arithmetic addition on them.
%%
Funky_Stuff
len=`wc -c < calctool.help`
if [ $len !=     5668 ] ; then
echo error: calctool.help was $len bytes long, should have been     5668
fi
fi # end of overwriting check