[net.sources] New version of calctool

richb@yarra.OZ (Rich Burridge) (11/25/86)

This is the new version of calctool for the Sun (version 1.1). It has a
couple of small bugs fixed and now correctly handles constants.

I thought I sent this a week ago, but it was still stuck in the system. I
apologise for the delay.

Many thanks to Richard Collins for pointing these out. I tried to mail you
the new version, but somewhere it bounced.

I did not expect so many requests for this, I'll have to write another trivial
program soon :-)

I have tried to reply to everybody who requested a copy, but if you didn't get
mail, then please treat this news article as a reply.

Regards Rich.

Rich Burridge            ISD:  +61 3 267-6222
Sun Australia            STD:  (03) 267-6222
14 Queens Rd,            ARPA: richb%yarra.oz@seismo.css.gov
Melbourne, VIC 3004.     UUCP: seismo!munnari!yarra.oz!richb
AUSTRALIA.               ACS:  richb@yarra.oz

-------------CUT HERE----------CUT HERE------------CUT HERE------------
#! /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 (not csh) to create:
#	README
#	Makefile
#	calctool.c
#	calctool.icon
# This archive created: Tue Nov 25 14:56:22 1986
# By:	Rich Burridge (Sun Computer Australia (Melbourne))
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'

  Calctool is a very simple little desktop calculator for the Sun
workstation running under V3.0 (or later) of the Sun O/S.

  It is based on the Sanyo cx250 pocket calculator, of which I have
a copy and of which I'm always losing. The first version of this
program was hastily put together. It was also my first real look at
Sunview, Suns own graphics package.

  This is the second version. It supercedes the first version and is
much cleaner. There were a couple of minor bug and I now correctly
handle constants. Feel free to do what you want with it but leave in
the initial comments for the source file.

Suggestion for improvement would be still most welcome plus bugs,
comments and flames to me.

Regards Rich.

Rich Burridge             ISD:   +61 3 267-6222
Sun Australia             STD:   (03) 267-6222
14 Queens Rd,             ARPA: richb%yarra.oz@seismo.arpa
Melbourne, VIC 3004.      UUCP: seismo!munnari!yarra.oz!richb
AUSTRALIA.                ACS:  richb@yarra.oz
SHAR_EOF
fi
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
#
#  Makefile for calctool, a desktop calculator for the Sun.
#
#  Copyright (c) Rich Burridge - SUN Australia - November 1986.
#
#  Version 1.1.
#
#  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        = -c -g
LDFLAGS       = -g
OBJS          = calctool.o
SRCS          = calctool.c
HDRS          =
LIBS          = -lm -lsuntool -lsunwindow -lpixrect
#
#  The following commands are declared.
#
all:            $(BINARIES)

release:        $(BINARIES)
		strip $(BINARIES)
#
#  General Makefile stuff.
#
backup:
		cp calctool.c calctool.c~
clean:
		rm -f *.o core
lint:
		lint $(SRCS) -lpixrect
#
#  calc specific stuff.
#
calctool:       $(OBJS)
		cc $(LDFLAGS) -o calctool $(OBJS) $(LIBS)

calctool.o:     calctool.c $(HDRS)
		cc $(CFLAGS) calctool.c
SHAR_EOF
fi
if test -f 'calctool.c'
then
	echo shar: "will not over-write existing file 'calctool.c'"
else
cat << \SHAR_EOF > 'calctool.c'

/*  calctool.c
 *
 *  This program looks and acts just like a simple desktop calculator.
 *  Copyright (c) Rich Burridge - Sun Australia - November 1986.
 *
 *  Version 1.1
 *
 *  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 <math.h>
#include <suntool/sunview.h>
#include <suntool/panel.h>

#define  SPRINTF        (void) sprintf   /* To make lint happy. */
#define  SSCANF         (void) sscanf
#define  STRCPY         (void) strcpy
#define  STRNCAT        (void) strncat

#define  BUTTON_BORDER   5               /* No of pixels in border. */
#define  BUTTON_COLS     4               /* No of columns of buttons. */
#define  BUTTON_GAP      5               /* No of pixels between buttons. */
#define  BUTTON_HEIGHT   25              /* Number of pixels for height. */
#define  BUTTON_ROWS     5               /* No of rows of buttons. */
#define  BUTTON_WIDTH    40              /* No of pixels for width. */
#define  DISPLAY         30              /* Calculators numerical display. */
#define  DISP_LENGTH     12              /* Length of display in characters. */
#define  MAXLINE         30              /* Length of character strings. */
#define  NOBUTTONS       BUTTON_ROWS * BUTTON_COLS

char *sprintf() ;
void button_press() ;
Frame frame ;
Panel panel1,panel2 ;
Panel_item display_item ;

short icon_image[] = {
#include "calctool.icon"
} ;
DEFINE_ICON_FROM_IMAGE(calctool_icon,icon_image) ;

double result ;                     /* Current calculator total value. */
double last_input ;                 /* Previous number input by user. */

int column ;                        /* Column number of key pressed. */
int error ;                         /* Indicates some kind of display error. */
int pointed ;                       /* Whether a decimal point has been given. */
int row ;                           /* Row number of key pressed. */
int started ;                       /* Indicates if number should be displayed. */
int toclear ;                       /* Indicates if display should be cleared. */

char bpress ;                       /* Current button pressed. */
char lastop ;                       /* Last operator key pressed. */
char obpress ;                      /* Previous button pressed. */
char operator ;                     /* Current arithmetic operation. */
char button_vals[NOBUTTONS][4] =    /* Calculator button values. */
       {
         "END", " C ", "SRT", "OFF",
         " 7 ", " 8 ", " 9 ", " X ",
         " 4 ", " 5 ", " 6 ", " / ",
         " 1 ", " 2 ", " 3 ", " - ",
         " 0 ", " . ", " = ", " + "
       } ;
char display[MAXLINE] ;             /* Current calculator display. */


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

{
  frame = window_create(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) ;

  panel1 = window_create(frame,PANEL,WIN_HEIGHT,DISPLAY,0) ;
  panel2 = window_create(frame,PANEL,WIN_BELOW,panel1,0) ;
  display_item = panel_create_item(panel1,PANEL_MESSAGE,
                                   PANEL_PAINT, PANEL_NO_CLEAR,
                                   0) ;
  initialise() ;              /* Initialise certain variables. */
  clear_display() ;
  for (row = 0; row < BUTTON_ROWS; row++)
    for (column = 0; column < BUTTON_COLS; column++)
      panel_create_item(panel2,PANEL_BUTTON,
         PANEL_LABEL_X,column*BUTTON_WIDTH+BUTTON_BORDER+(column*BUTTON_GAP),
         PANEL_LABEL_Y,row*BUTTON_HEIGHT+BUTTON_BORDER+(row*BUTTON_GAP),
         PANEL_LABEL_IMAGE,
           panel_button_image(panel2,button_vals[row*BUTTON_COLS+column],0,0),
         PANEL_NOTIFY_PROC,button_press,0) ;

  window_fit(panel2) ;
  window_fit(frame) ;
  window_main_loop(frame) ;
  exit(0) ;
}


clear_display()

{
  started = pointed = toclear = 0 ;
  STRCPY(display,"0.") ;
  make_display() ;
}


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

{
  double temp ;       /* Temporary total for this calculation. */

  if (bpress != '=' && lastop == '=') operator = '?' ;
  else temp = result ;
  if (bpress == 'R') operator = 'R' ;
  switch (operator)
    {
      case '?' : if (obpress == '=')                    /* Undefined. */
                   SSCANF(display,"%lf",&temp) ;
                 else temp = last_input ;
                 break ;
      case 'R' : SSCANF(display,"%lf",&temp) ;          /* Square root. */
                 temp = sqrt(temp) ;
                 break ;
      case '+' : temp += last_input ;
                 break ;
      case '-' : temp -= last_input ;
                 break ;
      case 'X' : temp *= last_input ;
                 break ;
      case '/' : temp /= last_input ;
                 break ;
      case '=' : break ;
    }

  SPRINTF(display,"%.10f",temp) ;
  make_result() ;
  toclear = 1 ;
  if (bpress != '=')
    {
      result = temp ;
      operator = bpress ;
    }
  if (bpress == '=' && lastop != '=') result = last_input ;
  lastop = bpress ;
}


initialise()

{
  error = 0 ;                 /* Currently no display error. */
  obpress = '\0' ;            /* No previous button pressed. */
  operator = '?' ;            /* No arithmetic operator defined yet. */
  lastop = '?' ;
  result = 0.0 ;              /* No previous result yet. */
  last_input = 0.0 ;
}


make_display()      /* Build up the calculators display - right justified. */

{
  char output[MAXLINE] ;

  SPRINTF(output,"%20s",display) ;
  panel_set(display_item,PANEL_LABEL_STRING,output,0) ;
}


make_result()       /* Display result of calculation. */

{
  char output[MAXLINE] ;
  int pnt = strlen(display)-1 ;

  while (display[pnt] != '.' && display[pnt] == '0') display[pnt--] = '\0' ;

  for (pnt = 0; pnt < strlen(display); pnt++)
    if (display[pnt] == '.') break ;

  if (pnt > DISP_LENGTH)
    {
      display[DISP_LENGTH-2] = '\0' ;
      SPRINTF(output,"E%18s.",display) ;
      error = 1 ;
    }
  else if (!strcmp(display,"Infinity"))
    {
      SPRINTF(output,"E%19s","0.") ;
      error = 1 ;
    }
  else if (display[0] == '-') SPRINTF(output,"-%19s",&display[1]) ;
  else SPRINTF(output,"%20s",display) ;
  panel_set(display_item,PANEL_LABEL_STRING,output,0) ;
}


/*ARGSUSED*/
static void button_press(item,event)
Panel_item item ;
Event *event ;

{
  int column,row ;

  column = (event_x(event) - BUTTON_BORDER) / (BUTTON_WIDTH + BUTTON_GAP) ;
  row = (event_y(event) - BUTTON_BORDER) / (BUTTON_HEIGHT + BUTTON_GAP) ;
  bpress = button_vals[row*BUTTON_COLS+column][1] ;

  if (error &&
      !(bpress == 'C' || bpress == 'N' || bpress == 'F')) return ;

  switch (bpress)
    {
      case 'N' : window_destroy(frame) ;              /* Terminate program. */
                 break ;
      case 'F' : window_set(frame,FRAME_CLOSED,TRUE,0) ;  /* Turn window iconic. */
                 break ;
      case 'C' : clear_display() ;
                 initialise() ;
                 break ;
      case '1' :
      case '2' :
      case '3' :
      case '4' :
      case '5' :
      case '6' :
      case '7' :
      case '8' :
      case '9' : started = 1 ;
      case '0' : if (toclear)
                   {
                     clear_display() ;
                     if (bpress != '0') started = 1 ;
                   }
                 if (strlen(display) < DISP_LENGTH)
                   if (pointed)
                     {
                       STRNCAT(display,&bpress,1) ;
                       make_display() ;
                     }
                   else if (started)
                     {
                       if (!strcmp(display,"0.")) display[0] = '\0' ;
                       display[strlen(display)-1] = '\0' ;
                       STRNCAT(display,&bpress,1) ;
                       STRNCAT(display,".",1) ;
                       make_display() ;
                     }
                 SSCANF(display,"%lf",&last_input) ;
                 break ;

      case 'R' :
      case '+' :
      case '-' :
      case 'X' :
      case '/' :
      case '=' : do_calculation() ;
                 break ;

      case '.' : if (toclear) clear_display() ;
                 if (strlen(display) < DISP_LENGTH)
                   if (!pointed) pointed = 1 ;
    }
  obpress = bpress ;
}
SHAR_EOF
fi
if test -f 'calctool.icon'
then
	echo shar: "will not over-write existing file 'calctool.icon'"
else
cat << \SHAR_EOF > 'calctool.icon'
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
 */
	0x9555,0x5555,0x5548,0x8888,0xAAAA,0xAAAA,0xAA88,0x8888,
	0x5555,0x5555,0x5562,0x2222,0xFFFF,0xFFFF,0xFEA2,0x2222,
	0x8000,0x0000,0x0348,0x8888,0xBFFF,0xFFFF,0xFA88,0x8888,
	0xA000,0x0000,0x0B62,0x2222,0xA000,0x0000,0x0AA2,0x2222,
	0xA600,0x2082,0x0B48,0x8888,0xA900,0x6186,0x0A88,0x8888,
	0xA200,0x2282,0x0B62,0x2222,0xA100,0x23C2,0x0AA2,0x2222,
	0xA908,0x2082,0x0B48,0x8888,0xA608,0x7087,0x0A88,0x8888,
	0xA000,0x0000,0x0B62,0x2222,0xA000,0x0000,0x0AA2,0x2222,
	0xBFFF,0xFFFF,0xFB48,0x8888,0x8000,0x0000,0x0288,0x8888,
	0x8000,0x0000,0x0362,0x2222,0xBFDF,0xEFF7,0xFAA2,0x2222,
	0xA050,0x2814,0x0B48,0x8888,0xAF53,0x2994,0x0A88,0x8888,
	0xA154,0xAA55,0x1362,0x2222,0xA253,0x2A54,0xAAA2,0x2222,
	0xA254,0xA9D4,0x4B48,0x8888,0xA454,0xA854,0xAA88,0x8888,
	0xA453,0x2995,0x1B62,0x2222,0xA050,0x2814,0x0AA2,0x2222,
	0xBFDF,0xEFF7,0xFB48,0x8888,0x8000,0x0000,0x0288,0x8888,
	0xBFDF,0xEFF7,0xFB62,0x2222,0xA050,0x2814,0x0AA2,0x2222,
	0xA257,0xA994,0x2B48,0x8888,0xA654,0x2A14,0x4A88,0x8888,
	0xAA57,0x2B94,0x4B62,0x2222,0xAF50,0xAA54,0x8AA2,0x2222,
	0xA254,0xAA54,0x8B48,0x8888,0xA253,0x2995,0x0A88,0x8888,
	0xA050,0x2814,0x0B62,0x2222,0xBFDF,0xEFF7,0xFAA2,0x2222,
	0x8000,0x0000,0x0348,0x8888,0xBFDF,0xEFF7,0xFA88,0x8888,
	0xA050,0x2814,0x0B62,0x2222,0xA253,0x2994,0x0AA2,0x2222,
	0xA654,0xAA54,0x0B48,0x8888,0xA250,0xA895,0xEA88,0x8888,
	0xA253,0x2854,0x0B62,0x2222,0xA254,0x2A54,0x0AA2,0x2222,
	0xA757,0xA994,0x0B48,0x8888,0xA050,0x2814,0x0A88,0x8888,
	0xBFDF,0xEFF7,0xFB62,0x2222,0x8000,0x0000,0x02A2,0x2222,
	0xBFDF,0xEFF7,0xFB48,0x8888,0xA050,0x2814,0x0A88,0x8888,
	0xA650,0x2814,0x0B62,0x2222,0xA950,0x2814,0x4AA2,0x2222,
	0xAB50,0x2BD4,0x4B48,0x8888,0xAD50,0x2815,0xFA88,0x8888,
	0xA951,0x2BD4,0x4B62,0x2222,0xA651,0x2814,0x4AA2,0x2222,
	0xA050,0x2814,0x0B48,0x8888,0xBFDF,0xEFF7,0xFA88,0x8888,
	0x8000,0x0000,0x0322,0x2222,0xFFFF,0xFFFF,0xFE22,0x2222
SHAR_EOF
fi
exit 0
#	End of shell archive
D
D

richb@yarra.OZ (Rich Burridge) (01/12/87)

This is version 1.2 of a simple desktop calculator, which can be a Sun Tool
and also works poorly on a normal ascii terminal in non-suntool mode.

It supercedes versions 1.0 and 1.1 which are no longer supported.

I am just about to change jobs, moving to Sun Microsystems here
in Australia, who currently haven't got a machine here on the net.
My account here on yarra will stay, but I probabily won't be able to
read it so readily, therefore please expect a delay in mail turnaround.

All suggestions, bugs, comments and flames to me please.

Regards Rich.

Rich Burridge,       ARPA: richb%yarra.oz@seismo.css.gov
Sun Microsystems     UUCP: seismo!munnari!yarra.oz!richb
AUSTRALIA.           ACS:  richb@yarra.oz

----------CUT HERE---------CUT HERE----------CUT HERE---------
#! /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 (not csh) to create:
#	README
#	Makefile
#	button.icon
#	calctool.icon
#	calctool.c
#	functions.c
#	calctool.h
#	calctool.help
#	help.cursor
# This archive created: Mon Jan 12 17:10:49 1987
# By:	Rich Burridge (Sun Microsystems Australia)
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'README'
then
	echo shar: "will not over-write existing file 'README'"
else
cat << \SHAR_EOF > 'README'

  calctool  -  README.

  This is V1.2 of a simple desktop calculator, which can be a Sun Tool
and also works poorly on a normal ascii terminal in non-suntool mode.
Mimimal changes should be needed to port this to other BSD and Sys V
machines.  Please let me know what changes if any you have to make to
get it working on your machine.

  It has a lot more features then the last version. These 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.

  This is a list of the calculator buttons with their equivalent keys:

  Button     Key     Action              Button    Key    Action
  ------     ---     ------              ------    ---    ------
    <<        <      Left shift           BIN       B     Binary base.
   OCT        O      Octal base           DEC       D     Decimal base.
   HEX        H      Hexidecimal base      >>       >     Right shift.
   STO        s      Store memory         RCL       r     Recall memory.
     D        d      Hex D (dec 13)         E       e     Hex E (dec 14).
     F        f      Hex F (dec 15)       CLR     DELETE  Clear display.
   NOT        ~      Logical NOT          SRT       S     Square root.
     A        a      Hex A (dec 10)         B       b     Hex B (dec 11).
     C        c      Hex C (dec 12)       BSP  BACKSPACE  Delete digit.
   AND        &      Logical AND           OR       |     Logical OR.
     7        7      Numeric 7              8       8     Numeric 8.
     9        9      Numeric 9              X       x     Multiplication.
   XOR        ^      Logical XOR          XNR       n     Logical XNOR.
     4        4      Numeric 4              5       5     Numeric 5.
     6        6      Numeric 6              /       /     Division.
   ACC        A      Accuracy             HLP       ?     Help.
     1        1      Numeric 1              2       2     Numeric 2.
     3        3      Numeric 3              -       -     Subtraction.
   OFF      ESC      Turn iconic          END       q     Quit.
     0        0      Numeric 0              .       .     Numeric point.
     =        =      Equals                 +       +     Addition.

   The following keys are also defined:

   Key     Action                        Key     Action
   ---     ------                        ---     ------
    X      Multiplication.             RETURN    Equals.
    Q      Quit                           N      Logical XNOR.

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

  Suggestions for furthur improvement would be most welcome, plus bugs,
comments and flames to me.

Regards Rich.

Rich Burridge             ARPA: richb%yarra.oz@seismo.css.gov
Sun Microsystems          UUCP: seismo!munnari!yarra.oz!richb
AUSTRALIA.                ACS:  richb@yarra.oz
SHAR_EOF
fi
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
#
#  Makefile for calctool, a simple calculator.
#
#  Copyright (c) Rich Burridge - January 1987.
#                Sun Microsystems, Australia - All rights reserved.
#
#  Version 1.2.
#
#  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.
#
#
#  <<<VERSION DEPENDENT DEFINITIONS (SPECIAL and LIBS).>>>
#
#  Suntool version.
#
#SPECIAL       = -DSUNTOOL
#LIBS          = -lm -lsuntool -lsunwindow -lpixrect
#
#  Other version.
#
SPECIAL       =
LIBS          = -lm
#   <<<END OF VERSION DEPENDENT DEFINITIONS.>>>


BINARIES      = calctool
BINDIR        = .
CFLAGS        = -g $(SPECIAL)
LDFLAGS       = -g
OBJS          = calctool.o functions.o
SRCS          = calctool.c functions.c
HDRS          = calctool.h
#
#  The following commands are declared.
#

all:            $(BINARIES)

release:        $(BINARIES)
		strip $(BINARIES)
#
#  General Makefile stuff.
#
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 specific stuff.
#
calctool:       $(OBJS)
		cc $(LDFLAGS) -o calctool $(OBJS) $(LIBS)

calctool.o:     calctool.c $(HDRS)
functions.o:    functions.c $(HDRS)
SHAR_EOF
fi
if test -f 'button.icon'
then
	echo shar: "will not over-write existing file 'button.icon'"
else
cat << \SHAR_EOF > 'button.icon'
/* 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
SHAR_EOF
fi
if test -f 'calctool.icon'
then
	echo shar: "will not over-write existing file 'calctool.icon'"
else
cat << \SHAR_EOF > 'calctool.icon'
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
 */
	0x9555,0x5555,0x5548,0x8888,0xAAAA,0xAAAA,0xAA88,0x8888,
	0x5555,0x5555,0x5562,0x2222,0xFFFF,0xFFFF,0xFEA2,0x2222,
	0x8000,0x0000,0x0348,0x8888,0xBFFF,0xFFFF,0xFA88,0x8888,
	0xA000,0x0000,0x0B62,0x2222,0xA000,0x0000,0x0AA2,0x2222,
	0xA600,0x2082,0x0B48,0x8888,0xA900,0x6186,0x0A88,0x8888,
	0xA200,0x2282,0x0B62,0x2222,0xA100,0x23C2,0x0AA2,0x2222,
	0xA908,0x2082,0x0B48,0x8888,0xA608,0x7087,0x0A88,0x8888,
	0xA000,0x0000,0x0B62,0x2222,0xA000,0x0000,0x0AA2,0x2222,
	0xBFFF,0xFFFF,0xFB48,0x8888,0x8000,0x0000,0x0288,0x8888,
	0x8000,0x0000,0x0362,0x2222,0xBFDF,0xEFF7,0xFAA2,0x2222,
	0xA050,0x2814,0x0B48,0x8888,0xAF53,0x2994,0x0A88,0x8888,
	0xA154,0xAA55,0x1362,0x2222,0xA253,0x2A54,0xAAA2,0x2222,
	0xA254,0xA9D4,0x4B48,0x8888,0xA454,0xA854,0xAA88,0x8888,
	0xA453,0x2995,0x1B62,0x2222,0xA050,0x2814,0x0AA2,0x2222,
	0xBFDF,0xEFF7,0xFB48,0x8888,0x8000,0x0000,0x0288,0x8888,
	0xBFDF,0xEFF7,0xFB62,0x2222,0xA050,0x2814,0x0AA2,0x2222,
	0xA257,0xA994,0x2B48,0x8888,0xA654,0x2A14,0x4A88,0x8888,
	0xAA57,0x2B94,0x4B62,0x2222,0xAF50,0xAA54,0x8AA2,0x2222,
	0xA254,0xAA54,0x8B48,0x8888,0xA253,0x2995,0x0A88,0x8888,
	0xA050,0x2814,0x0B62,0x2222,0xBFDF,0xEFF7,0xFAA2,0x2222,
	0x8000,0x0000,0x0348,0x8888,0xBFDF,0xEFF7,0xFA88,0x8888,
	0xA050,0x2814,0x0B62,0x2222,0xA253,0x2994,0x0AA2,0x2222,
	0xA654,0xAA54,0x0B48,0x8888,0xA250,0xA895,0xEA88,0x8888,
	0xA253,0x2854,0x0B62,0x2222,0xA254,0x2A54,0x0AA2,0x2222,
	0xA757,0xA994,0x0B48,0x8888,0xA050,0x2814,0x0A88,0x8888,
	0xBFDF,0xEFF7,0xFB62,0x2222,0x8000,0x0000,0x02A2,0x2222,
	0xBFDF,0xEFF7,0xFB48,0x8888,0xA050,0x2814,0x0A88,0x8888,
	0xA650,0x2814,0x0B62,0x2222,0xA950,0x2814,0x4AA2,0x2222,
	0xAB50,0x2BD4,0x4B48,0x8888,0xAD50,0x2815,0xFA88,0x8888,
	0xA951,0x2BD4,0x4B62,0x2222,0xA651,0x2814,0x4AA2,0x2222,
	0xA050,0x2814,0x0B48,0x8888,0xBFDF,0xEFF7,0xFA88,0x8888,
	0x8000,0x0000,0x0322,0x2222,0xFFFF,0xFFFF,0xFE22,0x2222
SHAR_EOF
fi
if test -f 'calctool.c'
then
	echo shar: "will not over-write existing file 'calctool.c'"
else
cat << \SHAR_EOF > 'calctool.c'

/*  calctool.c
 *
 *  This program looks and acts like a simple calculator.
 *
 *  Copyright (c) Rich Burridge - January 1987.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *  Version 1.2.
 *
 *  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"

#ifdef SUNTOOL
void canvas_proc() ;

Canvas canvas ;
Cursor main_cursor ;
Event event ;
Frame frame ;
Panel panel ;
Panel_item base_item, display_item ;
Pixwin *cpw ;
struct pixfont *sfont, *nfont ;

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"
} ;
DEFINE_ICON_FROM_IMAGE(calctool_icon,icon_image) ;
#else
struct sgttyb old,new ;
int found ;             /* Indicates if valid key value entered. */
#endif SUNTOOL
 
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[10] ;   /* Memory registers. */
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 toclear ;           /* Indicates if display should be cleared. */

/* 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. */
         { "SRT", 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, '\015' },
         { "   ", do_quit,        'Q' },
         { "   ", do_calculation, 'N' },
} ;

char display[MAXLINE] ;             /* Current calculator display. */


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

{
  nohelp = 0 ;
  if ((hfd = fopen(HELPNAME,"r")) == NULL)
    {
      FPRINTF(stderr,"Help file %s not found\r\n",HELPNAME) ;
      nohelp = 1 ;
    }

#ifdef SUNTOOL
  sfont = pf_open(SMALLFONT) ;      /* Open small point font. */
  nfont = pf_open(NORMALFONT) ;     /* Open normal sized font. */

  frame = window_create(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) ;

  panel = window_create(frame,PANEL,WIN_HEIGHT,DISPLAY,
                        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_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) ;
  main_cursor = window_get(canvas,WIN_CURSOR) ;
#endif SUNTOOL

  base = DEC ;                /* Initial base. */
  accuracy = 2 ;              /* Initial accuracy. */
  do_clear() ;                /* Initialise and clear display. */
  for (n = 0; n < 10; n++) mem_vals[n] = 0.0 ;   /* Clear memory registers. */

#ifdef SUNTOOL
  make_canvas() ;             /* Draw the calculators buttons. */
  window_fit(frame) ;
  window_main_loop(frame) ;
  exit(0) ;
#else
  IOCTL(fileno(stdin),TIOCGETP,&old) ;
  IOCTL(fileno(stdin),TIOCGETP,&new) ;
  new.sg_flags |= RAW ;
  IOCTL(fileno(stdin),TIOCSETP,&new) ;

  for (;;)
    {
      found = 0 ;
      while (!found)
        {
          READ(0,&c,1) ;
          for (n = 0; n < TOTAL_ITEMS; n++)
            if (c == buttons[n].value)
              {
                found = 1 ;
                break ;
              }
        }
      cur_value = buttons[n].value ;
      (*buttons[n].func)() ;
    }
#endif SUNTOOL
}


#ifdef SUNTOOL
/*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))
    {
      column = event_x(event) / (BUTTON_WIDTH + BUTTON_GAP) ;
      row = event_y(event) / (BUTTON_HEIGHT + BUTTON_GAP) ;
      n = row*BUTTON_COLS+column ;
    }
  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 ;
    
  cur_value = buttons[n].value ;
  if (error && cur_value != '\177') return ;    /* If error, must clear first. */

  (*buttons[n].func)() ;
}
#endif SUNTOOL


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") ;
    }
#ifdef SUNTOOL
  PANEL_SET(base_item,PANEL_LABEL_STRING,base_str,0) ;
#else
  FPRINTF(stdout,"%s\r\n",base_str) ;
#endif SUNTOOL
}


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

{
#ifdef SUNTOOL
  PANEL_SET(display_item,PANEL_VALUE_X,20+(MAX_DIGITS - strlen(display))*7,
                         PANEL_VALUE,display,
                         0) ;
#else
  FPRINTF(stdout,"%s\r\n",display) ;
#endif SUNTOOL
}


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

{
  int column,found,n,row ;
   
  found = 0 ;
  while (!found)
    {
#ifdef SUNTOOL
      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) ;
#else    
        {
          READ(0,&c,1) ;
#endif SUNTOOL
          for (n = 0; n < TOTAL_ITEMS; n++)
            if (c == buttons[n].value)
              {
                found = 1 ;
                break ;
              }
        }
    }
  return(n) ;
}
 
 
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 ;
}


#ifdef SUNTOOL
make_canvas()                /* Draw the calculators buttons. */

{
  int x ;

  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++)
      {
        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(buttons[row*BUTTON_COLS+column].str) == 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,
                          buttons[row*BUTTON_COLS+column].str) ;
      }
}
#endif SUNTOOL


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

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


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

{
  char *optr ;
  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") ;
      display_result(display) ;
      error = 1 ;
      return ;
    }

  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] ;
    }

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


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

{
#ifdef SUNTOOL
  pw_text(cpw,x,y,PIX_SRC,nfont,line) ;
#else
  FPRINTF(stdout,"%s\r\n",line) ;
#endif SUNTOOL
}
SHAR_EOF
fi
if test -f 'functions.c'
then
	echo shar: "will not over-write existing file 'functions.c'"
else
cat << \SHAR_EOF > 'functions.c'

/*  functions.c
 *
 *  This file contains the seperate functions used whenever a calculator
 *  button is pressed.
 *
 *  Copyright (c) Rich Burridge - January 1987.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *
 *  Version 1.2.
 *
 *  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 double convert_display() ;

#ifdef SUNTOOL
extern Canvas canvas ;
extern Cursor main_cursor ;
extern Event event ;
extern Frame frame ;
extern Pixwin *cpw ;
extern struct cursor help_cursor ;
#else
extern struct sgttyb old ;
#endif SUNTOOL

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[10] ;      /* Memory registers. */
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 ;
        }
    }
  make_number(disp_val) ;
}


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) ;
  make_number(disp_val) ;              /* Convert display value to current base. */
}


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'    :
      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'    :
      case 'N'    : temp = (BOOLEAN) result ^ (BOOLEAN) disp_val ;   /* XNOR. */
                    temp = ~((BOOLEAN) temp) ;
                    isboolean = 1 ;
                    break ;

      case '\015' :
      case '='    : break ;                                        /* Equals. */
    }

  if (isboolean) result = setbool(temp) ;
  make_number(result) ;
  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. */

{
#ifdef SUNTOOL
  window_set(frame,FRAME_CLOSED,TRUE,0) ;
#endif SUNTOOL
}


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 ;

  n = get_next_value() ;

#ifdef SUNTOOL
  window_set(canvas,WIN_CURSOR,&help_cursor,0) ;
  pw_writebackground(cpw,0,0,TOTAL_WIDTH,TOTAL_HEIGHT,PIX_CLR) ;
#endif SUNTOOL

  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 ;
        }
    }

#ifdef SUNTOOL
  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() ;
  window_set(canvas,WIN_CURSOR,main_cursor,0) ;
#endif SUNTOOL
}


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 ;
            }
          valid = 1 ;
        }
    }    
  make_number(disp_val) ;
}


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


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. */

{
#ifdef SUNTOOL
  window_destroy(frame) ;
#else
  IOCTL(fileno(stdin),TIOCSETP,&old) ;
  exit(0) ;
#endif SUNTOOL
}


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 ;
    }
  make_number(setbool(temp)) ;
  disp_val = last_input = convert_display() ;
}


do_sqrt()        /* Square root. */

{
  disp_val = sqrt(disp_val) ;
  make_number(disp_val) ;
}


double
setbool(p)
BOOLEAN p ;

{
  BOOLEAN q ;
  double val ;

  q = p & 0x80000000 ;
  p &= 0x7fffffff ;
  val = (double) p ;
  if (q) val += 2147483648.0 ;
  return(val) ;
}
SHAR_EOF
fi
if test -f 'calctool.h'
then
	echo shar: "will not over-write existing file 'calctool.h'"
else
cat << \SHAR_EOF > 'calctool.h'

/*  calctool.c
 *
 *  This files contains all the definitions used by the calctool program.
 *
 *  Copyright (c) Rich Burridge - January 1987.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *  Version 1.2.
 *
 *  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>

#ifdef SUNTOOL
#include <suntool/sunview.h>
#include <suntool/canvas.h>
#include <suntool/panel.h>
#else
#include <sgtty.h>
#endif SUNTOOL

char *sprintf() ;

#define  PATCHLEVEL     0

#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  STRCPY         (void) strcpy
#define  STRNCAT        (void) strncat

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

#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          4                /* 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  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 ;
} ;
SHAR_EOF
fi
if test -f 'calctool.help'
then
	echo shar: "will not over-write existing file 'calctool.help'"
else
cat << \SHAR_EOF > 'calctool.help'
%<<%
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.
%%

%SRT%
Square root            ( s or 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         ( 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               ( ? ).

All internal operations in double
precision floating point. The
display can be used with the GET
and PUT function keys with other
Sunview windows.

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.
%%
SHAR_EOF
fi
if test -f 'help.cursor'
then
	echo shar: "will not over-write existing file 'help.cursor'"
else
cat << \SHAR_EOF > 'help.cursor'
/* 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
SHAR_EOF
fi
exit 0
#	End of shell archive
D
D