4 * Copyright (c) 1987-2006 Sun Microsystems, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
32 #include <glib/gi18n.h>
35 #define MP_SIZE 150 /* Size of the multiple precision values. */
37 #define FCLOSE (void) fclose /* To make lint happy. */
38 #define FPRINTF (void) fprintf
39 #define FPUTS (void) fputs
40 #define GETHOSTNAME (void) gethostname
41 #define MEMCPY (void) memcpy
42 #define MEMSET (void) memset
43 #define MKSTEMP (void) mkstemp
44 #define REWIND (void) rewind
45 #define SPRINTF (void) sprintf
46 #define SSCANF (void) sscanf
47 #define STRCAT (void) strcat
48 #define STRCPY (void) strcpy
49 #define STRNCAT (void) strncat
50 #define UNLINK (void) unlink
52 /* Menu bar menu types. */
54 enum mb_type
{ M_ABOUT
, M_ASCII
, M_BASIC
, M_ADV
, M_CONTENTS
, M_COPY
, M_FIN
,
55 M_PASTE
, M_QUIT
, M_REGS
, M_SCI
, M_EXP
, M_TSEP
, M_ZEROES
};
57 enum base_type
{ BIN
, OCT
, DEC
, HEX
}; /* Base definitions. */
59 /* Main calctool window types. */
60 enum fcp_type
{ FCP_KEY
, FCP_REG
, FCP_MODE
};
62 enum item_type
{ BASEITEM
, TTYPEITEM
, NUMITEM
,
63 HYPITEM
, INVITEM
, OPITEM
, MODEITEM
};
65 /* Popup menu types. */
66 enum menu_type
{ M_ACC
, M_CON
, M_EXCH
, M_FUN
, M_LSHF
,
67 M_RCL
, M_RSHF
, M_STO
, M_NONE
70 /* Calculator modes. */
71 enum mode_type
{ BASIC
, ADVANCED
, FINANCIAL
, SCIENTIFIC
};
73 enum num_type
{ ENG
, FIX
, SCI
}; /* Number display mode. */
76 enum res_type
{ R_ACCURACY
, R_BASE
, R_DISPLAY
, R_MODE
, R_REGS
, R_TRIG
,
77 R_ZEROES
, R_TSEP
, R_SYNTAX
,
78 R_REG0
, R_REG1
, R_REG2
, R_REG3
, R_REG4
,
79 R_REG5
, R_REG6
, R_REG7
, R_REG8
, R_REG9
82 enum trig_type
{ DEG
, GRAD
, RAD
}; /* Trigonometric types. */
84 enum trig_func
{SIN
=0, COS
=1, TAN
=2};
86 /* Abbreviations for the gcalctool keyboard and menu equivalents. */
88 #define KEY_DIV a_buttons[3] /* / */
89 #define KEY_LPAR a_buttons[4] /* ( */
90 #define KEY_BSP a_buttons[5] /* Control-h */
91 #define KEY_CE a_buttons[6] /* Control-Backspace */
93 #define KEY_MUL a_buttons[11] /* * */
94 #define KEY_RPAR a_buttons[12] /* ) */
96 #define KEY_CHS a_buttons[13] /* C */
97 #define KEY_INT a_buttons[14] /* i */
98 #define KEY_STO a_buttons[15] /* S */
100 #define KEY_SUB a_buttons[19] /* - */
101 #define KEY_PER a_buttons[20] /* % */
102 #define KEY_SQRT a_buttons[21] /* s */
103 #define KEY_FRAC a_buttons[22] /* : */
104 #define KEY_RCL a_buttons[23] /* R */
106 #define KEY_EQ a_buttons[26] /* = */
107 #define KEY_ADD a_buttons[27] /* + */
108 #define KEY_REC a_buttons[28] /* r */
109 #define KEY_SQR a_buttons[29] /* @ */
110 #define KEY_ABS a_buttons[30] /* u */
111 #define KEY_EXCH a_buttons[31] /* X */
113 #define KEY_CTRM f_buttons[0] /* m */
114 #define KEY_DDB f_buttons[1] /* D */
115 #define KEY_FV f_buttons[2] /* v */
116 #define KEY_PMT f_buttons[3] /* P */
117 #define KEY_PV f_buttons[4] /* p */
118 #define KEY_RATE f_buttons[5] /* T */
119 #define KEY_SLN f_buttons[6] /* l */
120 #define KEY_SYD f_buttons[7] /* Y */
121 #define KEY_TERM f_buttons[8] /* T */
123 #define KEY_LSFT s_buttons[0] /* < */
124 #define KEY_RSFT s_buttons[1] /* > */
125 #define KEY_16 s_buttons[2] /* [ */
126 #define KEY_32 s_buttons[3] /* ] */
127 #define KEY_MOD s_buttons[6] /* M */
128 #define KEY_ACC s_buttons[7] /* A */
130 #define KEY_CON s_buttons[8] /* # */
131 #define KEY_FUN s_buttons[9] /* F */
132 #define KEY_ETOX s_buttons[11] /* { */
133 #define KEY_TTOX s_buttons[12] /* } */
134 #define KEY_YTOX s_buttons[13] /* y */
135 #define KEY_FACT s_buttons[14] /* ! */
136 #define KEY_RAND s_buttons[15] /* ? */
138 #define KEY_COS s_buttons[19] /* J */
139 #define KEY_SIN s_buttons[20] /* K */
140 #define KEY_TAN s_buttons[21] /* L */
141 #define KEY_LN s_buttons[22] /* N */
142 #define KEY_LOG s_buttons[23] /* G */
144 #define KEY_OR s_buttons[27] /* | */
145 #define KEY_AND s_buttons[28] /* & */
146 #define KEY_NOT s_buttons[29] /* ~ */
147 #define KEY_XOR s_buttons[30] /* ^ */
148 #define KEY_XNOR s_buttons[31] /* n */
150 #define BCOLS 4 /* No of columns of Basic Mode buttons. */
151 #define BROWS 5 /* No of rows of Basic Mode buttons. */
153 #define ACOLS 8 /* No of columns of Advanced Mode buttons. */
154 #define AROWS 4 /* No of rows of Advanced Mode buttons. */
156 #define FCOLS 8 /* No of columns of Financial Mode buttons. */
157 #define FROWS 2 /* No of rows of Financial Mode buttons. */
159 #define SCOLS 8 /* No of columns of Scientific Mode buttons. */
160 #define SROWS 4 /* No of rows of Scientific Mode buttons. */
162 #define EQUAL(a, b) (strlen(a)==strlen(b)) & !strcmp(a, b)
164 #define INC { argc--; argv++; }
165 #define IS_KEY(v, n) (v == n)
169 #define LINT_CAST(arg) (arg ? 0 : 0)
171 #define LINT_CAST(arg) (arg)
175 #define MAX_DIGITS 40 /* Maximum displayable number of digits. */
176 #define MAX_LOCALIZED (MAX_DIGITS * (1 + MB_LEN_MAX) + MB_LEN_MAX)
178 /* Maximum number of various graphics pieces. */
179 #define MAXITEMS 8 /* Maximum number of panel items. */
180 #define MAXMENUS 9 /* Maximum number of popup menus. */
183 #define MAXLINE 256 /* Length of character strings. */
186 #define MAXACC 30 /* Max. number of digits after numeric point. */
187 #define MAXBASES 4 /* Maximum number of numeric bases. */
188 #define MAXCONFUN 10 /* Maximum number of constants/functions. */
189 #define MAXDISPMODES 3 /* Maximum number of display modes. */
190 #define MAXEXTRAS 8 /* Maximum number of keysym alternates. */
191 #define MAXMODES 4 /* Maximum number of calculator modes. */
192 #define MAXREGS 10 /* Maximum number of memory registers. */
193 #define MAXSTACK 256 /* Parenthese stack size. */
194 #define MAXTRIGMODES 3 /* Maximum number of trig. modes. */
195 #define MAXVKEYS 1 /* Number of valid keys after an error. */
196 #define MAXSYNTAX 2 /* Number of syntaxes in calculator */
198 #define MCOLS 8 /* Number of columns of "special" keys. */
199 #define MROWS 2 /* Number of rows of "special" keys. */
200 #define MODEKEYS MCOLS * MROWS
203 #define MIN(x,y) ((x) < (y) ? (x) : (y))
206 #define B_NOBUTTONS BROWS * BCOLS /* Number of Basic Mode buttons. */
207 #define A_NOBUTTONS AROWS * ACOLS /* Number of Advanced Mode buttons. */
208 #define F_NOBUTTONS FROWS * FCOLS /* Number of Financial Mode buttons. */
209 #define S_NOBUTTONS SROWS * SCOLS /* Number of Scientific Mode buttons. */
212 #define CFNAME ".gcalctoolcf"
216 #define RCNAME ".gcalctoolrc"
219 #ifndef TRUE /* Boolean definitions. */
227 #define UNDO_HISTORY_LENGTH 16 /* Arithmetic mode undo history length */
229 typedef unsigned long BOOLEAN
;
232 none
= 0, /* No flags */
233 binop
= 1, /* Is binary operation ie. A op B */
234 unop
= (1 << 1), /* Is unary operation ie. op A. */
235 enter
= (1 << 2), /* Expression is entered */
236 number
= (1 << 3), /* Number button */
237 immediate
= (1 << 4), /* Button does immediate function */
239 parenthesis
= (1 << 5), /* Parenthesis */
240 func
= (1 << 6), /* Function */
241 bsp
= (1 << 7), /* Backspace */
242 clear
= (1 << 8), /* Clear display */
243 neg
= (1 << 9), /* Negate display */
244 inv
= (1 << 10), /* Reciprocial */
245 con
= (1 << 11), /* Constant */
246 regrcl
= (1 << 12), /* Recall register */
247 expnum
= (1 << 13), /* Exponential number */
248 postfixop
= (1 << 14), /* Unary postfix operation */
249 prefixop
= (1 << 15), /* Unary prefix operation */
250 dpoint
= (1 << 16) /* Decimal point */
259 npa
= 0, /* Non-precedence arithmetic */
260 exprs
, /* Expression with arithmetic precedence */
264 char *str
; /* Button display string. */
265 char *hstr
; /* Button help string. */
266 char *astr
; /* AccessibleName string (if tooltip not useful) */
267 guint mods
[MAXEXTRAS
]; /* Keyboard modifiers (Shift, Ctrl, ...). */
268 guint value
[MAXEXTRAS
]; /* Button keyboard equivalents. */
269 char func_char
; /* Unique function string character. */
270 enum menu_type mtype
; /* Type of popup menu (if any). */
271 void (*func
)(); /* Function to obey on button press. */
272 char *symname
; /* Expression function name */
273 enum button_flags flags
; /* Misc flags */
276 struct exprm_state
{ /* Expression mode state */
277 struct button button
; /* Current button/character pressed. */
278 int ans
[MP_SIZE
]; /* Previously calculated answer */
279 char *expression
; /* Expression entered by user */
282 /* Circular list of Arithmetic Precedence Mode states*/
283 struct exprm_state_history
{
286 unsigned int current
;
287 struct exprm_state e
[UNDO_HISTORY_LENGTH
]; /* Expression mode state */
291 char *title
; /* Menu title. */
292 int total
; /* Number of menu entries. */
293 int index
; /* Index into menu string array. */
294 int defval
; /* Default menu item position (from 1). */
297 struct calcVars
{ /* Calctool variables and options. */
298 struct exprm_state_history h
; /* History of expression mode states */
300 struct button
*pending_but
; /* Button info. for pending op. */
301 struct button
*current
; /* Current button/character pressed. */
303 char *appname
; /* Application name for resources. */
304 char con_names
[MAXREGS
][MAXLINE
]; /* Selectable constant names. */
305 char display
[MAXLINE
]; /* Current calculator display. */
306 char *exp_posn
; /* Position of the exponent sign. */
307 char fnum
[MAX_DIGITS
]; /* Scratchpad for fixed numbers. */
308 char fun_names
[MAXREGS
][MAXLINE
]; /* Function names from .gcalctoolcf. */
309 char fun_vals
[MAXREGS
][MAXLINE
]; /* Function defs from .gcalctoolcf. */
310 char *home
; /* Pathname for users home directory. */
311 char *iconlabel
; /* The calctool icon label. */
312 char op_item_text
[5]; /* Operand item panel string. */
313 char opstr
[5]; /* Operand string during pending op. */
314 char *progname
; /* Name of this program. */
315 char pstr
[5]; /* Current button text string. */
316 const char *radix
; /* Locale specific radix string. */
317 char *shelf
; /* PUT selection shelf contents. */
318 char snum
[MAX_DIGITS
]; /* Scratchpad for scientific numbers. */
319 const char *tsep
; /* Locale specific thousands seperator. */
320 char *titleline
; /* Value of titleline (if present). */
321 char *tool_label
; /* Title line for calculator window. */
323 int MPcon_vals
[MAXREGS
][MP_SIZE
]; /* Selectable constants. */
324 int MPdebug
; /* If set, debug info. to stderr. */
325 int MPerrors
; /* If set, output errors to stderr. */
326 int MPdisp_val
[MP_SIZE
]; /* Value of the current display. */
327 int MPexpr_val
[MP_SIZE
]; /* Value of the current expression. */
328 int MPlast_input
[MP_SIZE
]; /* Previous number input by user. */
329 int MPmvals
[MAXREGS
][MP_SIZE
]; /* Memory register values. */
330 int *MPnumstack
[MAXSTACK
]; /* Numeric stack for parens. */
331 int MPresult
[MP_SIZE
]; /* Current calculator total value. */
332 int MPimresult
[MP_SIZE
]; /* Current intermediate result. */
333 int MPtresults
[3][MP_SIZE
]; /* Current trigonometric results. */
335 enum base_type base
; /* Current base: BIN, OCT, DEC or HEX. */
336 enum fcp_type curwin
; /* Window current event occured in. */
337 enum mode_type modetype
; /* Current calculator mode. */
338 enum num_type dtype
; /* Number display mode. */
339 enum trig_type ttype
; /* Trig. type (deg, grad or rad). */
341 enum syntax syntax
; /* Calculation syntax mode */
343 int accuracy
; /* Number of digits precision (Max 9). */
344 int beep
; /* Indicates whether there is a beep sound on error. */
345 int cur_ch
; /* Current character if keyboard event. */
346 int cur_op
; /* Current arithmetic operation. */
347 int doing_mi
; /* Set if adjusting the "show zeroes" menu item. */
348 int down
; /* Indicates is a mouse button is down. */
349 int error
; /* Indicates some kind of display error. */
350 int hyperbolic
; /* If set, trig functions will be hyperbolic. */
351 int iconic
; /* Set if window is currently iconic. */
352 int inverse
; /* If set, trig and log functions will be inversed. */
353 int ismenu
; /* Set when do_pending called via a popup menu. */
354 int key_exp
; /* Set if entering exponent number. */
355 int ndisplay
; /* Height of the numerical display. */
356 int new_input
; /* New number input since last op. */
357 int noparens
; /* Count of left brackets still to be matched. */
358 int numsptr
; /* Pointer into the parenthese numeric stack. */
359 int old_cal_value
; /* Previous calculation operator. */
360 int opsptr
; /* Pointer into the parentheses operand stack. */
361 int opstack
[MAXSTACK
]; /* Stack containing parentheses input. */
362 int pending
; /* Set for command depending on multiple presses. */
363 int pending_op
; /* Arithmetic operation for pending command. */
364 int pointed
; /* Whether a decimal point has been given. */
365 int rstate
; /* Indicates if memory register frame is displayed. */
366 int show_paren
; /* Set if we wish to show DISPLAYITEM during parens. */
367 int show_tsep
; /* Set if the thousands seperator should be shown. */
368 int show_zeroes
; /* Set if trailing zeroes should be shown. */
369 int started
; /* Set just before window is displayed. */
370 int toclear
; /* Indicates if display should be cleared. */
371 int warn_change_mode
; /* Should we warn user when changing modes? */
374 typedef struct calcVars
*Vars
;
377 /* MP definitions. */
379 #define C_abs(x) ((x) >= 0 ? (x) : -(x))
380 #define dabs(x) (double) C_abs(x)
381 #define min(a, b) ((a) <= (b) ? (a) : (b))
382 #define max(a, b) ((a) >= (b) ? (a) : (b))
383 #define dmax(a, b) (double) max(a, b)
384 #define dmin(a, b) (double) min(a, b)
386 struct button
*button_for_fc(char);
387 struct button
*button_for_value(int);
388 struct button
*copy_button_info(struct button
*);
390 void syntaxdep_show_display();
391 char *button_str(int);
392 char *convert(char *);
393 char *gc_strdup(char *str
);
394 const char *get_radix();
395 char *get_resource(enum res_type
);
396 const char *get_tsep();
397 char *make_fixed(int *, char *, int, int, int);
398 char *make_number(int *, int, BOOLEAN
);
401 char *get_localized_numeric_point(void);
403 unsigned short *get_but_data();
405 int button_mods(int);
406 int button_value(int);
408 int do_rcl_reg(int reg
, int value
[MP_SIZE
]);
409 int do_sto_reg(int reg
, int value
[MP_SIZE
]);
410 int do_tfunc(int s
[MP_SIZE
], int t
[MP_SIZE
], enum trig_func tfunc
);
411 int get_menu_entry(enum menu_type
, int);
412 int key_equal(struct button
*, struct button
);
413 int main(int, char **);
416 void build_word_map();
417 void clear_display(int);
418 void display_prop_sheet();
419 void do_base(enum base_type
);
423 void do_expression();
424 void do_calctool(int, char **);
426 void do_clear_entry();
428 void do_numtype(enum num_type
);
440 void do_trigtype(enum trig_type
);
443 void get_constant(int);
444 void get_function(int);
445 void get_options(int, char **);
446 void grey_buttons(enum base_type
);
447 void handle_menu_selection(struct button
*, int);
450 void init_frame_sizes();
452 void init_Xvars(int *, char **);
454 void localize_number(char *, const char *);
455 void load_resources();
458 void make_reg(int, char *);
459 void make_registers();
461 void MPstr_to_num(char *, enum base_type
, int *);
462 void paren_disp(int);
463 void process_item(struct button
*);
464 void process_str(char *);
465 void push_num(int *);
467 void put_resource(enum res_type
, char *);
469 void read_resources();
470 void read_str(char **, char *);
471 void refresh_display();
472 void save_pending_values(struct button
*);
473 void save_resources();
474 void set_accuracy_menu_item(int);
475 void set_accuracy_tooltip(int);
476 void set_display(char *, int);
477 void write_display(char *);
478 void set_error_state(int);
479 void set_hyp_item(int);
481 void set_inv_item(int);
482 void set_main_title(enum mode_type
);
483 void set_mode(enum mode_type
);
484 void set_title(enum fcp_type
, char *);
485 void show_change_mode_dialog();
486 void show_display(int *);
487 void show_error(char *);
491 void str_replace(char **, char *, char *);
492 void switch_hands(int);
493 void update_statusbar(gchar
*, const gchar
*);
495 void win_display(enum fcp_type
, int);
496 void set_redo_and_undo_button_sensitivity(int undo
, int redo
);
498 /* Global Brent MP routines in mp.c. */
499 int mpeq(int *, int *);
500 int mpge(int *, int *);
501 int mpgt(int *, int *);
502 int mple(int *, int *);
503 int mplt(int *, int *);
505 void mpabs(int *, int *);
506 void mpadd(int *, int *, int *);
507 void mpaddi(int *, int *, int *);
508 void mpasin(int *, int *);
509 void mpatan(int *, int *);
510 void mpcdm(double *, int *);
511 void mpcim(int *, int *);
512 void mpcmd(int *, double *);
513 void mpcmf(int *, int *);
514 void mpcmi(int *, int *);
515 void mpcmim(int *, int *);
516 void mpcos(int *, int *);
517 void mpcosh(int *, int *);
518 void mpdiv(int *, int *, int *);
519 void mpdivi(int *, int *, int *);
520 void mpexp(int *, int *);
521 void mpln(int *, int *);
522 void mpmul(int *, int *, int *);
523 void mpmuli(int *, int *, int *);
524 void mpneg(int *, int *);
526 void mppwr(int *, int *, int *);
527 void mppwr2(int *, int *, int *);
528 void mpset(int *, int *, int *);
529 void mpsin(int *, int *);
530 void mpsinh(int *, int *);
531 void mpsqrt(int *, int *);
532 void mpstr(int *, int *);
533 void mpsub(int *, int *, int *);
534 void mptanh(int *, int *);
536 #endif /*CALCTOOL_H*/