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