File: calctool.c

package info (click to toggle)
calctool 2.4.9-10
  • links: PTS
  • area: non-free
  • in suites: hamm, slink
  • size: 432 kB
  • ctags: 1,165
  • sloc: ansic: 5,130; makefile: 613; sh: 22
file content (390 lines) | stat: -rw-r--r-- 18,192 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390

/*  @(#)calctool.c 1.12 89/12/07
 *
 *  A simple calculator program.
 *
 *  Copyright (c) Rich Burridge.
 *                Sun Microsystems, Australia - All rights reserved.
 *
 *  Basic algorithms, copyright (c) Ed Falk.
 *                Sun Microsystems, Mountain View.
 *
 *  Permission is given to distribute these sources, as long as the
 *  copyright messages are not removed, and no monies are exchanged.
 *
 *  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 "patchlevel.h"
#include "color.h"
#include "calctool.h"

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

double exp_p1[10][4] = {
        { 1.0,          1.0,             1.0,    1.0             },
        { 1.0,          1.0,             1.0,    1.0             },
        { 0.5,          0.125,           0.1,    0.0625          },
        { 0.25,         0.015625,        0.01,   3.90625e-03     },
        { 0.125,        1.953125e-03,    0.001,  2.44140625e-04  },
        { 0.0625,       2.44140625e-04,  1.0e-4, 1.525878906e-05 },
        { 0.03125,      3.051757813e-05, 1.0e-5, 9.536743164e-07 },
        { 0.015625,     3.814697266e-06, 1.0e-6, 5.960464478e-08 },
        { 0.0078125,    4.768371582e-07, 1.0e-7, 3.725290298e-09 },
        { 3.90625e-03,  5.960464478e-08, 1.0e-8, 2.328306437e-10 }
} ;

double max_fix[4] = {
          6.871947674e+10, 3.245185537e+32,
          1.000000000e+36, 2.230074520e+43
} ;

/* Selectable constants - these are the default selections. */

double con_vals[MAXREGS] = {
         0.621,                   /* kilometres per hour <=> miles per hour. */
         1.41421356237309504880,  /* square root of 2. */
         2.7182818284590452354,   /* e */
         3.14159265358979323846,  /* pi */
         2.54,                    /* centimetres <=> inch. */
         57.29577951308232,       /* degrees in a radian. */
         1048576.0,               /* 2 ^ 20. */
         0.0353,                  /* grams <=> ounce. */
         0.948,                   /* kilojoules <=> British thermal units. */
         0.0610,                  /* cubic cms <=> cubic inches. */
} ;

char con_names[MAXREGS][MAXLINE] = {
       "kilometres per hour <=> miles per hour.",
       "square root of 2.",
       "e.",
       "pi.",
       "centimetres <=> inch.",
       "degrees in a radian.",
       "2 ^ 20.",
       "grams <=> ounce.",
       "kilojoules <=> British thermal units.",
       "cubic cms <=> cubic inches.",
} ;

char num_names[MAXREGS][2] = {    /* Used by the popup menus. */
       "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
} ;

char base_str[4][4]  = { "BIN", "OCT", "DEC", "HEX" } ;
char dtype_str[2][4] = { "FIX", "SCI" } ;
char ttype_str[3][5] = { "DEG", "GRAD", "RAD" } ;

char digits[] = "0123456789abcdef" ;
int basevals[4] = {2, 8, 10, 16} ;

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

/* X offset in pixels for various length button strings. */
int chxoff[5] = { 5, 9, 14, 16, 5 } ;

/* Valid keys when an error condition has occured. */
/*                            MEM  KEYS HELP   clr   QUIT OFF  REDRAW */
char validkeys[MAXVKEYS]  = { 'M', 'K', '?', '\177', 'q', 'o', '\f' } ;

/* Valid keys for which the right mouse button will get a popup menu. */
char validmenu[MAXMENUS]  = {
/*   ACC  CON    EXCH        FUN        <    >   RCL  STO  */
     'A', '#', CCTRL('e'), CCTRL('f'), '<', '>', 'r', 's'
} ;

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. */
double tresults[3] ;          /* Current trigonometric results. */

enum base_type base ;         /* Current base: BIN, OCT, DEC or HEX. */
enum gr_type gtype ;          /* What graphics system is being used. */
enum num_type dtype ;         /* Number display mode. */
enum trig_type ttype ;        /* Trigonometric type (deg, grad or rad). */

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

int accuracy ;      /* Number of digits precision (Max 9). */
int color ;         /* Color being used for current raster operation. */
int column ;        /* Column number of current key/mouse press. */
int cur_ch ;        /* Current character if keyboard event. */
int curx ;          /* Current mouse X position. */
int cury ;          /* Current mouse Y position. */
int down ;          /* Indicates is a mouse button is down. */
int error ;         /* Indicates some kind of display error. */
int hyperbolic ;    /* If set, trig functions will be hyperbolic. */
int iconic ;        /* Set if window is currently iconic. */
int inv_video ;     /* Set if user wants inverse video mode. */
int inverse ;       /* If set, trig and log functions will be inversed. */
int iscolor ;       /* Set if this is a color screen. */
int ishelp ;        /* Set if there is a help file. */
int issel ;         /* Set if valid [Get] selection. */
int ix ;            /* Initial X position of the icon. */
int iy ;            /* Initial Y position of the icon. */
int key_exp ;       /* Set if entering exponent number. */
int new_input ;     /* New number input since last op. */
int nextc ;         /* Current event identifier. */
int nfont_width ;   /* Width of the normal font characters. */
int pending ;       /* Indicates command depending on multiple presses. */
int pending_op ;    /* Arithmetic operation for pending command. */
int pointed ;       /* Whether a decimal point has been given. */
int portion ;       /* Portion of button on current key/mouse press. */
int posspec ;       /* Set if -Wp or -g option is present (for X11) */
int row ;           /* Row number of current key/mouse press. */
int rstate ;        /* Indicates if memory register frame is displayed. */
int spaces ;        /* Number of spaces in current button string. */
int toclear ;       /* Indicates if display should be cleared. */
int tstate ;        /* Indicates current button set being displayed. */
int wx ;            /* Initial X position of the window. */
int wy ;            /* Initial Y position of the window. */
int x ;             /* X offset for text for button. */
int y ;             /* Y offset for text for button. */

/* Routines obeyed by mouse button or character presses. */
int close_frame(),    destroy_frame(),  do_base() ;
int do_calculation(), do_clear(),       do_constant(),  do_delete() ;
int do_expno(),       do_immediate(),   do_keys(),      do_number() ;
int do_pending(),     do_point(),       do_portion(),   do_repaint() ;
int do_set_mode(),    do_trig(),        do_trigtype(),  toggle_reg_canvas() ;

char cur_op ;                     /* Current arithmetic operation. */
char current ;                    /* Current button or character pressed. */
char *exp_posn ;                  /* Position of the exponent sign. */
char fnum[MAX_DIGITS+1] ;         /* Scratch area for fixed point numbers. */
char fun_names[MAXREGS][MAXLINE] ;  /* Function defs from .calctoolrc. */
char fun_vals[MAXREGS][MAXLINE] ;   /* Function names from .calctoolrc. */
char geometry[MAXLINE] ;          /* X11 geometry information. */
char old_cal_value ;              /* Previous calculation operator. */
char pstr[5] ;                    /* Current button text string. */
char *selection ;                 /* Current [Get] selection. */
char *shelf ;                     /* PUT selection shelf contents. */
char snum[MAX_DIGITS+1] ;         /* Scratch are for scientific numbers. */
char x11_display[MAXLINE] ;       /* X11 display information. */

struct iteminfo items[MAXITEMS] = {                    /* Panel items. */
  { SFONT, BBORDER,                 DISPLAY-3,  "" },  /* BASEITEM. */
  { NFONT, 0,                       DISPLAY-15, "" },  /* DISPLAYITEM. */
  { SFONT, BBORDER+1*(BWIDTH+BGAP), DISPLAY-3,  "" },  /* TTYPEITEM. */
  { SFONT, BBORDER+2*(BWIDTH+BGAP), DISPLAY-3,  "" },  /* NUMITEM. */
  { SFONT, BBORDER+3*(BWIDTH+BGAP), DISPLAY-3,  "" },  /* HYPITEM. */
  { SFONT, BBORDER+4*(BWIDTH+BGAP), DISPLAY-3,  "" },  /* INVITEM. */
  { SFONT, BBORDER+5*(BWIDTH+BGAP), DISPLAY-3,  "" },  /* OPITEM. */
} ;

/* Calculator button values. */

struct button buttons[TITEMS] = {
  { "EXCH", CCTRL('e'), OP_SET,   MAUVE,    do_pending },       /* Row 1. */
  { "CON ", '#',        OP_SET,   BLUE,     do_pending },
  { "BIN ", 'B',        OP_CLEAR, YELLOW,   do_base },
  { "MEM ", 'M',        OP_CLEAR, BLUE,     toggle_reg_canvas },
  { "OCT ", 'O',        OP_CLEAR, YELLOW,   do_base },
  { "D   ", 'd',        OP_NOP,   PINK,     do_number },
  { "DEC ", 'D',        OP_CLEAR, YELLOW,   do_base },
  { "E   ", 'e',        OP_NOP,   PINK,     do_number }, 
  { "HEX ", 'H',        OP_CLEAR, YELLOW,   do_base },
  { "F   ", 'f',        OP_NOP,   PINK,     do_number },  
  { "SCI ", CCTRL('n'), OP_CLEAR, BLUE,     do_set_mode },
  { "FUN ", CCTRL('f'), OP_SET,   BLUE,     do_pending },

  { "&32 ", '[',        OP_CLEAR, LGREY,    do_immediate },      /* Row 2. */
  { "STO ", 's',        OP_SET,   MAUVE,    do_pending },
  { "&16 ", ']',        OP_CLEAR, LGREY,    do_immediate },
  { "RCL ", 'r',        OP_SET,   MAUVE,    do_pending }, 
  { "<   ", '<',        OP_SET,   LGREY,    do_pending },
  { "A   ", 'a',        OP_NOP,   PINK,     do_number }, 
  { ">   ", '>',        OP_SET,   LGREY,    do_pending },
  { "B   ", 'b',        OP_NOP,   PINK,     do_number },
  { "%   ", '%',        OP_SET,   LPURPLE,  do_calculation },
  { "C   ", 'c',        OP_NOP,   PINK,     do_number },
  { "clr ", '\177',     OP_CLEAR, BLUE,     do_clear },
  { "bsp ", CCTRL('h'), OP_NOP,   BLUE,     do_delete },

  { "OR  ", '|',        OP_SET,   GREEN,    do_calculation },   /* Row 3. */
  { "AND ", '&',        OP_SET,   GREEN,    do_calculation },
  { "HYP ", 'h',        OP_CLEAR, BLUE,     do_set_mode },
  { "SIN ", CCTRL('s'), OP_CLEAR, LGREEN,   do_trig },
  { "e^x ", '{',        OP_CLEAR, ORANGE,   do_immediate },
  { "7   ", '7',        OP_NOP,   LBLUE,    do_number },
  { "10^x", '}',        OP_CLEAR, ORANGE,   do_immediate },
  { "8   ", '8',        OP_NOP,   LBLUE,    do_number },
  { "y^x ", 'Y',        OP_SET,   ORANGE,   do_calculation },
  { "9   ", '9',        OP_NOP,   LBLUE,    do_number }, 
  { "INT ", 'I',        OP_CLEAR, LGREY,    do_portion },
  { "X   ", 'x',        OP_SET,   LPURPLE,  do_calculation },

  { "XNOR", 'n',        OP_SET,   GREEN,    do_calculation },   /* Row 4. */
  { "XOR ", '^',        OP_SET,   GREEN,    do_calculation },
  { "INV ", 'i',        OP_CLEAR, BLUE,     do_set_mode },
  { "COS ", CCTRL('c'), OP_CLEAR, LGREEN,   do_trig },
  { "ln  ", 'N',        OP_CLEAR, ORANGE,   do_immediate },
  { "4   ", '4',        OP_NOP,   LBLUE,    do_number },
  { "log ", 'G',        OP_CLEAR, ORANGE,   do_immediate },
  { "5   ", '5',        OP_NOP,   LBLUE,    do_number },
  { "SQRT", 'S',        OP_CLEAR, ORANGE,   do_immediate },
  { "6   ", '6',        OP_NOP,   LBLUE,    do_number },
  { "FRAC", 'F',        OP_CLEAR, LGREY,    do_portion },
  { "/   ", '/',        OP_SET,   LPURPLE,  do_calculation },

  { "NOT ", '~',        OP_CLEAR, GREEN,    do_immediate },     /* Row 5. */
  { "ACC ", 'A',        OP_SET,   BLUE,     do_pending },
  { "EXP ", 'E',        OP_SET,   BLUE,     do_expno },
  { "TAN ", CCTRL('t'), OP_CLEAR, LGREEN,   do_trig },
  { "1/x ", 'R',        OP_CLEAR, ORANGE,   do_immediate },
  { "1   ", '1',        OP_NOP,   LBLUE,    do_number },
  { "x!  ", '!',        OP_CLEAR, ORANGE,   do_immediate },
  { "2   ", '2',        OP_NOP,   LBLUE,    do_number },
  { "x^2 ", '@',        OP_CLEAR, ORANGE,   do_immediate },
  { "3   ", '3',        OP_NOP,   LBLUE,    do_number },
  { "CHS ", 'C',        OP_CLEAR, LGREY,    do_immediate },
  { "-   ", '-',        OP_SET,   LPURPLE,  do_calculation },

  { "QUIT", 'q',        OP_CLEAR, BLUE,     destroy_frame },    /* Row 6. */
  { "OFF ", 'o',        OP_CLEAR, BLUE,     close_frame },
  { "KEYS", 'K',        OP_CLEAR, BLUE,     do_keys },
  { "?   ", '?',        OP_SET,   BLUE,     do_pending },
  { "DEG ", CCTRL('d'), OP_CLEAR, RED,      do_trigtype },
  { "0   ", '0',        OP_NOP,   LBLUE,    do_number },
  { "RAD ", CCTRL('r'), OP_CLEAR, RED,      do_trigtype },
  { ".   ", '.',        OP_NOP,   LPURPLE,  do_point },
  { "GRAD", CCTRL('g'), OP_CLEAR, RED,      do_trigtype },
  { "=   ", '=',        OP_CLEAR, LPURPLE,  do_calculation },
  { "ABS ", 'U',        OP_CLEAR, LGREY,    do_portion },
  { "+   ", '+',        OP_SET,   LPURPLE,  do_calculation },

/* Extra definitions. */

  { "X   ", 'X',        OP_SET,   WHITE,    do_calculation },
  { "X   ", '*',        OP_SET,   WHITE,    do_calculation },
  { "    ", CCTRL('m'), OP_CLEAR, WHITE,    do_calculation },
  { "QUIT", 'Q',        OP_CLEAR, WHITE,    destroy_frame },
  { "    ", '\f',       OP_NOP,   WHITE,    do_repaint },
} ;

/*  256-byte table for quickly reversing the bits in an unsigned 8-bit char,
 *  used to convert between MSBFirst and LSBFirst image formats.
 */

char revtable[256] = {
        0, -128,   64,  -64,   32,  -96,   96,  -32,
       16, -112,   80,  -48,   48,  -80,  112,  -16,
        8, -120,   72,  -56,   40,  -88,  104,  -24,
       24, -104,   88,  -40,   56,  -72,  120,   -8,
        4, -124,   68,  -60,   36,  -92,  100,  -28,
       20, -108,   84,  -44,   52,  -76,  116,  -12,
       12, -116,   76,  -52,   44,  -84,  108,  -20,
       28, -100,   92,  -36,   60,  -68,  124,   -4,
        2, -126,   66,  -62,   34,  -94,   98,  -30,
       18, -110,   82,  -46,   50,  -78,  114,  -14,
       10, -118,   74,  -54,   42,  -86,  106,  -22,
       26, -102,   90,  -38,   58,  -70,  122,   -6,
        6, -122,   70,  -58,   38,  -90,  102,  -26,
       22, -106,   86,  -42,   54,  -74,  118,  -10,
       14, -114,   78,  -50,   46,  -82,  110,  -18,
       30,  -98,   94,  -34,   62,  -66,  126,   -2,
        1, -127,   65,  -63,   33,  -95,   97,  -31,
       17, -111,   81,  -47,   49,  -79,  113,  -15,
        9, -119,   73,  -55,   41,  -87,  105,  -23,
       25, -103,   89,  -39,   57,  -71,  121,   -7,
        5, -123,   69,  -59,   37,  -91,  101,  -27,
       21, -107,   85,  -43,   53,  -75,  117,  -11,
       13, -115,   77,  -51,   45,  -83,  109,  -19,
       29,  -99,   93,  -35,   61,  -67,  125,   -3,
        3, -125,   67,  -61,   35,  -93,   99,  -29,
       19, -109,   83,  -45,   51,  -77,  115,  -13,
       11, -117,   75,  -53,   43,  -85,  107,  -21,
       27, -101,   91,  -37,   59,  -69,  123,   -5,
        7, -121,   71,  -57,   39,  -89,  103,  -25,
       23, -105,   87,  -41,   55,  -73,  119,   -9,
       15, -113,   79,  -49,   47,  -81,  111,  -17,
       31,  -97,   95,  -33,   63,  -65,  127,   -1,
} ;

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. */
  get_helpfile(helpname) ;    /* Open helpfile if present. */
  read_rcfiles() ;            /* Read .calctoolrc's files. */
  if (init_ws_type())         /* Determine window system type. */
    {
      FPRINTF(stderr,"Error initialising window system.\n") ;
      exit(1) ;
    }
  init_fonts() ;              /* Open required fonts. */
  make_icon() ;               /* Set up the calctool window icon. */
  make_frames(argc, argv) ;   /* Create calctool window frames. */
  make_subframes() ;          /* Create panels and canvases. */
  make_menus() ;              /* Create menus for graphics versions. */
  if (gtype != X11) load_colors() ;  /* Load the initial calctool colormap. */

  shelf = NULL ;              /* No selection for shelf initially. */
  pending = 0 ;               /* No initial pending command. */
  rstate = 0 ;                /* No memory register frame display initially. */
  tstate = 0 ;                /* Button values displayed first. */
  hyperbolic = 0 ;            /* Normal trig functions initially. */
  inverse = 0 ;               /* No inverse functions initially. */
  base = DEC ;                /* Initial base. */
  ttype = DEG ;               /* Initial trigonometric type. */
  dtype = FIX ;               /* Initial number display mode. */
  down = 0 ;                  /* No mouse presses initially. */

  make_items() ;              /* Create panel items and cursors. */
  do_clear() ;                /* Initialise and clear display. */
  set_cursor(MAINCURSOR) ;    /* Initially display the arrow cursor. */
  start_tool() ;              /* Display the calculator. */
  exit(0) ;
}


/* Calctools' customised math library error-handling routine. */

doerr(funcname, etype, eval)
char *funcname, *etype ;
int eval ;
{
  SPRINTF(display, "%s: %s error", funcname, etype) ;
  set_item(DISPLAYITEM, display) ;
  error = eval ;
  set_item(OPITEM, "CLR") ;
}


/* Default math library exception handling routine. */

/*ARGSUSED*/
matherr(exc)
struct exception *exc ;
{
  STRCPY(display, "Error") ;
  set_item(DISPLAYITEM, display) ;
  error = 1 ;
  set_item(OPITEM, "CLR") ;
}