dockapps/wmcalc/wmcalcswitch.c
2015-01-10 19:02:57 +00:00

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