DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T c

⟦6393380fb⟧ TextFile

    Length: 14562 (0x38e2)
    Types: TextFile
    Names: »calctool.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/calctool/calctool.c« 

TextFile


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