603 lines
15 KiB
C
603 lines
15 KiB
C
/****************************************************************
|
|
* File: wmcalcswitch.c
|
|
* Version: 0.21
|
|
* Date: November 1, 2000
|
|
* Author: Edward H. Flora <ehflora@access1.net>
|
|
*
|
|
* This file is a part of the wmcalc application. As such, this
|
|
* file is licensed under the GNU General Public License, version 2.
|
|
* A copy of this license may be found in the file COPYING that should
|
|
* have been distributed with this file. If not, please refer to
|
|
* http://www.gnu.org/copyleft/gpl.html for details.
|
|
*
|
|
****************************************************************
|
|
Description:
|
|
This file contains system level functions, such as read/write of
|
|
the config file, character map boundaries, etc.
|
|
|
|
Change History:
|
|
Date Modification
|
|
11/1/00 Updated Function headers, cleaned up comments some.
|
|
|
|
****************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include "wmcalc_err.h"
|
|
#include "wmcalc_c.h"
|
|
#include "wmcalc_f.h"
|
|
|
|
/****************************************************************
|
|
* Function: ExecFunc
|
|
****************************************************************
|
|
Description:
|
|
This function determines which button was pressed, and performs
|
|
the appropriate function.
|
|
|
|
Change History:
|
|
Date Modification
|
|
11/01/00 Function header updated
|
|
****************************************************************/
|
|
void ExecFunc( int val ) {
|
|
extern int Verbose;
|
|
|
|
if (Verbose) printf("Execute function for button %d\n", val);
|
|
|
|
switch(val) {
|
|
case 100:
|
|
clearcalc();
|
|
break;
|
|
case 101:
|
|
sqrtnum();
|
|
break;
|
|
case 102:
|
|
charkey('7');
|
|
break;
|
|
case 103:
|
|
charkey('8');
|
|
break;
|
|
case 104:
|
|
charkey('9');
|
|
break;
|
|
case 105:
|
|
divnums();
|
|
break;
|
|
case 106:
|
|
sqrnum();
|
|
break;
|
|
case 107:
|
|
charkey('4');
|
|
break;
|
|
case 108:
|
|
charkey('5');
|
|
break;
|
|
case 109:
|
|
charkey('6');
|
|
break;
|
|
case 110:
|
|
multnums();
|
|
break;
|
|
case 111:
|
|
// scinotation();
|
|
startcalc();
|
|
break;
|
|
case 112:
|
|
charkey('1');
|
|
break;
|
|
case 113:
|
|
charkey('2');
|
|
break;
|
|
case 114:
|
|
charkey('3');
|
|
break;
|
|
case 115:
|
|
subtnums();
|
|
break;
|
|
case 116:
|
|
chgsignnum();
|
|
break;
|
|
case 117:
|
|
charkey('0');
|
|
break;
|
|
case 118:
|
|
charkey('.');
|
|
break;
|
|
case 119:
|
|
equalfunc();
|
|
break;
|
|
case 120:
|
|
addnums();
|
|
break;
|
|
case 200:
|
|
clrallmem();
|
|
break;
|
|
case 201:
|
|
sqrtnum();
|
|
// userdef201();
|
|
break;
|
|
case 202:
|
|
recallmem(7);
|
|
break;
|
|
case 203:
|
|
recallmem(8);
|
|
break;
|
|
case 204:
|
|
recallmem(9);
|
|
break;
|
|
case 205:
|
|
divnums();
|
|
// userdef205();
|
|
break;
|
|
case 206:
|
|
sqrnum();
|
|
// userdef206();
|
|
break;
|
|
case 207:
|
|
recallmem(4);
|
|
break;
|
|
case 208:
|
|
recallmem(5);
|
|
break;
|
|
case 209:
|
|
recallmem(6);
|
|
break;
|
|
case 210:
|
|
multnums();
|
|
// userdef210();
|
|
break;
|
|
case 211:
|
|
startcalc();
|
|
break;
|
|
case 212:
|
|
recallmem(1);
|
|
break;
|
|
case 213:
|
|
recallmem(2);
|
|
break;
|
|
case 214:
|
|
recallmem(3);
|
|
break;
|
|
case 215:
|
|
subtnums();
|
|
// userdef215();
|
|
break;
|
|
case 216:
|
|
chgsignnum();
|
|
break;
|
|
case 217:
|
|
recallmem(0);
|
|
break;
|
|
case 218:
|
|
// userdef218();
|
|
break;
|
|
case 219:
|
|
equalfunc();
|
|
break;
|
|
case 220:
|
|
addnums();
|
|
// userdef220();
|
|
break;
|
|
case 300:
|
|
clearnum();
|
|
break;
|
|
case 301:
|
|
sqrtnum();
|
|
// userdef301();
|
|
break;
|
|
case 302:
|
|
stormem(7);
|
|
break;
|
|
case 303:
|
|
stormem(8);
|
|
break;
|
|
case 304:
|
|
stormem(9);
|
|
break;
|
|
case 305:
|
|
divnums();
|
|
// userdef305();
|
|
break;
|
|
case 306:
|
|
sqrnum();
|
|
// userdef306();
|
|
break;
|
|
case 307:
|
|
stormem(4);
|
|
break;
|
|
case 308:
|
|
stormem(5);
|
|
break;
|
|
case 309:
|
|
stormem(6);
|
|
break;
|
|
case 310:
|
|
multnums();
|
|
// userdef310();
|
|
break;
|
|
case 311:
|
|
startcalc();
|
|
break;
|
|
case 312:
|
|
stormem(1);
|
|
break;
|
|
case 313:
|
|
stormem(2);
|
|
break;
|
|
case 314:
|
|
stormem(3);
|
|
break;
|
|
case 315:
|
|
subtnums();
|
|
// userdef315();
|
|
break;
|
|
case 316:
|
|
chgsignnum();
|
|
break;
|
|
case 317:
|
|
stormem(0);
|
|
break;
|
|
case 318:
|
|
// userdef318();
|
|
break;
|
|
case 319:
|
|
equalfunc();
|
|
break;
|
|
case 320:
|
|
addnums();
|
|
// userdef320();
|
|
break;
|
|
} /* End of switch statement */
|
|
|
|
} /* End of function ExecFunc() *********************************/
|
|
|
|
/****************************************************************
|
|
* Function: getboundaries
|
|
****************************************************************
|
|
Description:
|
|
This function returns the x,y boundaries for each character
|
|
that is to be displayed on the display.
|
|
|
|
There must be a better way to do this, as by changing the file
|
|
charmap.xpm, one may have to adjust these constants.
|
|
|
|
Change History:
|
|
Date Modification
|
|
11/01/00 Function header updated
|
|
10/30/00 Added characters for the Memory indicator bar.
|
|
****************************************************************/
|
|
ButtonArea getboundaries(char ch) {
|
|
ButtonArea xybounds;
|
|
|
|
switch (ch) {
|
|
case '0':
|
|
xybounds.x = 1; xybounds.i = 6;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '1':
|
|
xybounds.x = 7; xybounds.i = 12;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '2':
|
|
xybounds.x = 13; xybounds.i = 18;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '3':
|
|
xybounds.x = 19; xybounds.i = 24;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '4':
|
|
xybounds.x = 25; xybounds.i = 30;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '5':
|
|
xybounds.x = 31; xybounds.i = 36;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '6':
|
|
xybounds.x = 37; xybounds.i = 42;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '7':
|
|
xybounds.x = 43; xybounds.i = 48;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '8':
|
|
xybounds.x = 49; xybounds.i = 54;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '9':
|
|
xybounds.x = 55; xybounds.i = 60;
|
|
xybounds.y = 1; xybounds.j = 8;
|
|
break;
|
|
case '+':
|
|
xybounds.x = 55; xybounds.i = 60;
|
|
xybounds.y = 28; xybounds.j = 35;
|
|
break;
|
|
case '-':
|
|
xybounds.x = 49; xybounds.i = 54;
|
|
xybounds.y = 28; xybounds.j = 35;
|
|
break;
|
|
case '.':
|
|
xybounds.x = 7; xybounds.i = 12;
|
|
xybounds.y = 10; xybounds.j = 17;
|
|
break;
|
|
case 'e':
|
|
xybounds.x = 1; xybounds.i = 6;
|
|
xybounds.y = 37; xybounds.j = 44;
|
|
break;
|
|
case 'i':
|
|
xybounds.x = 7; xybounds.i = 12;
|
|
xybounds.y = 37; xybounds.j = 44;
|
|
break;
|
|
case 'j':
|
|
xybounds.x = 13; xybounds.i = 18;
|
|
xybounds.y = 37; xybounds.j = 44;
|
|
break;
|
|
case 'n':
|
|
xybounds.x = 19; xybounds.i = 24;
|
|
xybounds.y = 37; xybounds.j = 44;
|
|
break;
|
|
case 'a':
|
|
xybounds.x = 25; xybounds.i = 30;
|
|
xybounds.y = 37; xybounds.j = 44;
|
|
break;
|
|
case 'f':
|
|
xybounds.x = 31; xybounds.i = 36;
|
|
xybounds.y = 37; xybounds.j = 44;
|
|
break;
|
|
case ' ':
|
|
xybounds.x = 1; xybounds.i = 6;
|
|
xybounds.y = 10; xybounds.j = 17;
|
|
break;
|
|
case '=':
|
|
xybounds.x = 55; xybounds.i = 60;
|
|
xybounds.y = 55; xybounds.j = 56;
|
|
break;
|
|
case '#':
|
|
xybounds.x = 55; xybounds.i = 60;
|
|
xybounds.y = 57; xybounds.j = 58;
|
|
break;
|
|
case '_':
|
|
xybounds.x = 55; xybounds.i = 60;
|
|
xybounds.y = 59; xybounds.j = 60;
|
|
break;
|
|
default:
|
|
xybounds.x = 1; xybounds.i = 6;
|
|
xybounds.y = 10; xybounds.j = 17;
|
|
break;
|
|
} /* end of switch statement */
|
|
|
|
return(xybounds);
|
|
} /***** End of function getboundaries() ************************/
|
|
|
|
/****************************************************************
|
|
* Function: write_config
|
|
****************************************************************
|
|
Description:
|
|
This function updates the configuration file as memory locations
|
|
are updated in the program. It re-writes the entire file, but
|
|
should ignore all lines that do not start with "Mem".
|
|
|
|
Change History:
|
|
Date Modification
|
|
11/01/00 Function Header updated
|
|
11/05/00 Added Locked Memory Handling
|
|
****************************************************************/
|
|
int write_config(void) {
|
|
extern int Verbose;
|
|
extern double MemArray[];
|
|
extern char configfile[];
|
|
extern char tempfile[];
|
|
extern char *CfgVarList[];
|
|
FILE *fp, *fptmp;
|
|
char *line = NULL;
|
|
int mem_ndx = 0;
|
|
int err_code = OKAY;
|
|
char movefilecmd[2 * CONFIGFILEMAX + 10]; /* make sure enough room in string */
|
|
|
|
/* Open current Config file */
|
|
if ((fp = fopen(configfile, "r")) == NULL) { // Can't find config file
|
|
printf("%s: Cannot create configuration file\n", configfile);
|
|
return(ERR_FILE_NOT_FOUND);
|
|
}
|
|
|
|
/* We cannot write to the global config-file... */
|
|
if(!strcmp(configfile, CONFIGGLOBAL)) {
|
|
strcpy(configfile, getenv("HOME")); // Added to wmbutton by Gordon Fraser, 9/21/01
|
|
strcat(configfile, CONFFILENAME);
|
|
}
|
|
|
|
/* Open Temporary File */
|
|
if ((fptmp = fopen(tempfile, "w")) == NULL) { // Can't open file in /tmp
|
|
fprintf(stderr, "%s: Temporary File Open Failed\n", tempfile);
|
|
strcpy(tempfile, getenv("HOME"));
|
|
strcat(tempfile, "wmcalc.tmp");
|
|
if ((fptmp = fopen(tempfile, "w")) == NULL) { // Can't open file in HOME
|
|
fprintf(stderr, "%s: Temporary File Open Failed\n", tempfile);
|
|
return(ERR_TMP_FILE_FAILED);
|
|
}
|
|
}
|
|
|
|
while ((line = readln(fp)) != NULL) { // Read Lines in config file
|
|
if (Verbose) printf("line:%s", line);
|
|
|
|
if ((strncmp(line, CfgVarList[MEM_LABEL_0],
|
|
strlen(CfgVarList[MEM_LABEL_0]) - 1) == 0)) {
|
|
// -1 to generalize to all Mem? strings
|
|
// If we've found a memory entry
|
|
mem_ndx = atoi(line+strlen(CfgVarList[MEM_LABEL_0])-1);
|
|
if ((mem_ndx >= 0) && (mem_ndx <= (NUM_MEM_CELLS - 1))) {
|
|
fprintf(fptmp, "%s\t%f\n", CfgVarList[mem_ndx],
|
|
MemArray[mem_ndx]);
|
|
}
|
|
}
|
|
else {
|
|
fprintf(fptmp, "%s", line);
|
|
}
|
|
free(line);
|
|
} /* End of while loop */
|
|
|
|
/* Close open files */
|
|
fclose(fp);
|
|
fclose(fptmp);
|
|
|
|
/* Copy temp file over original */
|
|
/* Note: If changing command, make sure to adjust size of string above!! */
|
|
sprintf(movefilecmd, "mv -f %s %s\n", tempfile, configfile);
|
|
err_code = system(movefilecmd);
|
|
|
|
if(Verbose) printf("New config file written.\n");
|
|
|
|
return(err_code);
|
|
} /***** End of function write_config() *************************/
|
|
|
|
|
|
/****************************************************************
|
|
* Function: read_config
|
|
****************************************************************
|
|
Description:
|
|
This function reads the configuration file on program startup,
|
|
and sets the appropriate configuration options.
|
|
(By default, this is ~/.wmcalc, or a user set value)
|
|
|
|
Change History:
|
|
Date Modification
|
|
11/01/00 Function header updated.
|
|
11/05/00 Added Lcoked Memory Capabilities
|
|
****************************************************************/
|
|
int read_config(void) {
|
|
extern int Verbose;
|
|
extern double MemArray[];
|
|
extern int MemLock[];
|
|
extern char *CfgVarList[];
|
|
extern char ImagChar;
|
|
extern char configfile[];
|
|
extern char SysCalcCmd[];
|
|
FILE *fp;
|
|
int i = 0;
|
|
int err_code = OKAY;
|
|
char *line = NULL;
|
|
char sep_ch = '\t';
|
|
char *cfg_var_ptr = NULL;
|
|
|
|
|
|
if ((fp = fopen(configfile, "r")) == NULL) { // Can't find config file
|
|
strcpy(configfile, CONFIGGLOBAL); // ...so try to open global config
|
|
if ((fp = fopen(configfile, "r")) == NULL) { // Can't find global config file
|
|
fprintf(stderr, "%s: Configuration File not found\n", configfile);
|
|
return(ERR_FILE_NOT_FOUND);
|
|
} else {
|
|
write_config(); // if global config opened, save in homedir
|
|
}
|
|
}
|
|
else {
|
|
if (Verbose) printf("%s: Found Configuration File\n", configfile);
|
|
}
|
|
|
|
do { // Read Lines in config file
|
|
line = readln(fp);
|
|
if (Verbose) printf("Line Read:%s\n", line);
|
|
if (line == NULL) break; // if end of file, quit
|
|
if ( (line[0] != '#') && (line[0] != '\n')) { /* Ignore comments and
|
|
blanks */
|
|
if (strchr(line, sep_ch) != NULL) { /* The line has a tab, so let's
|
|
see if the variable is
|
|
understood */
|
|
i = 0;
|
|
/* Loop while we haven't found the variable */
|
|
while (((strncmp(line, CfgVarList[i], strlen(CfgVarList[i]))) != 0)
|
|
&& (i < MAX_LABEL)) {
|
|
i++;
|
|
}
|
|
/* If we've found the variable, let's set the appropriate value */
|
|
if (i <= MAX_LABEL) {
|
|
if (Verbose) printf("Variable %s found\n", CfgVarList[i]);
|
|
|
|
/* Point to the 'tab' character, to read the value */
|
|
cfg_var_ptr = strchr(line, sep_ch);
|
|
cfg_var_ptr++; // ++ to avoid tab character itself
|
|
|
|
/* Now set the appropriate variable */
|
|
switch(i) {
|
|
case MEM_LABEL_0:
|
|
case MEM_LABEL_1:
|
|
case MEM_LABEL_2:
|
|
case MEM_LABEL_3:
|
|
case MEM_LABEL_4:
|
|
case MEM_LABEL_5:
|
|
case MEM_LABEL_6:
|
|
case MEM_LABEL_7:
|
|
case MEM_LABEL_8:
|
|
case MEM_LABEL_9:
|
|
/* Set Locked Flag */
|
|
MemLock[i] = 0;
|
|
/* Set Memory Element */
|
|
MemArray[i] = atof(cfg_var_ptr);
|
|
if (Verbose)
|
|
printf("Assign Memory Element %d to %f\n", i, MemArray[i]);
|
|
break;
|
|
|
|
case MEM_LOCK_0:
|
|
case MEM_LOCK_1:
|
|
case MEM_LOCK_2:
|
|
case MEM_LOCK_3:
|
|
case MEM_LOCK_4:
|
|
case MEM_LOCK_5:
|
|
case MEM_LOCK_6:
|
|
case MEM_LOCK_7:
|
|
case MEM_LOCK_8:
|
|
case MEM_LOCK_9:
|
|
/* Set Locked Flag */
|
|
MemLock[i - MEM_LOCK_0] = 1;
|
|
/* Set Memory Element */
|
|
MemArray[i - MEM_LOCK_0] = atof(cfg_var_ptr);
|
|
if (Verbose)
|
|
printf("Assign Memory Element %d to %f\n", i -
|
|
MEM_LOCK_0, MemArray[i - MEM_LOCK_0]);
|
|
break;
|
|
|
|
case IMAG_LABEL:
|
|
/* Get the character that the user wishes to use to
|
|
represent sqrt(-1) (i or j) */
|
|
if ((cfg_var_ptr[0] == 'i') || cfg_var_ptr[0] == 'j') {
|
|
ImagChar = cfg_var_ptr[0];
|
|
}
|
|
if (Verbose)
|
|
printf("Use character '%c' to represent sqrt(-1)\n", ImagChar);
|
|
break;
|
|
|
|
case CALC_LABEL:
|
|
/* Set external calculator start command */
|
|
strcpy(SysCalcCmd, cfg_var_ptr);
|
|
if (Verbose)
|
|
printf("Assign Calc Command: %s\n", cfg_var_ptr);
|
|
break;
|
|
|
|
default:
|
|
if (Verbose) printf("Unknown Config Variable: %s\n", line);
|
|
break;
|
|
}
|
|
|
|
}
|
|
/* Otherwise, we don't recognize the variable */
|
|
else {
|
|
if (Verbose) printf("Unknown Config Variable: %s\n", line);
|
|
}
|
|
}
|
|
/* Otherwise, we had a poorly formatted line in the config file. */
|
|
else {
|
|
if (Verbose) printf("Poorly formatted config file line\n:%s\n", line);
|
|
}
|
|
}
|
|
free(line);
|
|
} while (line != NULL);
|
|
|
|
fclose(fp);
|
|
|
|
|
|
|
|
return(err_code);
|
|
} /***** End of function read_config **************************/
|