diff options
Diffstat (limited to 'input.c')
-rw-r--r-- | input.c | 977 |
1 files changed, 469 insertions, 508 deletions
@@ -22,13 +22,13 @@ int showing_err = 0; char input_buf[MAXIN]; int iptr; -double value, saved, stored=0; +double value, saved, stored = 0; void paste(void); void copy(void); int number_is_ok(double n) { - return (fpclassify(n) & (FP_ZERO | FP_NORMAL )); + return (fpclassify(n) & (FP_ZERO | FP_NORMAL)); } void bell(void) { @@ -36,532 +36,493 @@ void bell(void) { XBell(display, 0); } -void -convert_number() -{ - char *ip = input_buf; - double scale = 1; - int sign = +1; - - if (*ip == '-') - sign = -1; - value = 0; - while (*++ip) - { - if (*ip == '.') - break; - if (*ip >= '0' && *ip <= '9') - { - value *= base; - value += *ip-'0'; - } - if (*ip >= 'a' && *ip <= 'f') - { - value *= base; - value += *ip-'a'+10; - } - } - if (*ip) - while (*++ip) - { - if (*ip >= '0' && *ip <= '9') - { - scale *= base; - value += (*ip-'0')/scale; - } - if (*ip >= 'a' && *ip <= 'f') - { - scale *= base; - value += (*ip-'a'+10)/scale; - } - } - value *= sign; +void convert_number() { + char *ip = input_buf; + double scale = 1; + int sign = +1; + + if(*ip == '-') + sign = -1; + value = 0; + while(*++ip) { + if(*ip == '.') + break; + if(*ip >= '0' && *ip <= '9') { + value *= base; + value += *ip - '0'; + } + if(*ip >= 'a' && *ip <= 'f') { + value *= base; + value += *ip - 'a' + 10; + } + } + if(*ip) + while(*++ip) { + if(*ip >= '0' && *ip <= '9') { + scale *= base; + value += (*ip - '0') / scale; + } + if(*ip >= 'a' && *ip <= 'f') { + scale *= base; + value += (*ip - 'a' + 10) / scale; + } + } + value *= sign; } -void -show_value() -{ - char tmp[25], *tp; - char commas[40], *cp, *dp; - double v = value; - - if(!number_is_ok(value)) { - set_string("Err"); - bell(); - showing_err = 1; - saved = value = 0; /* so it doesn't get saved on exit! */ - return; - } - - if (base == 2) - { - int q = (long long)v & 0xffffffffL; - set_bits(q); - return; - } - - tmp[0] = ' '; - if (v < 0) - { - tmp[0] = '-'; - v = -v; - } - - if (base == 10) - { - sprintf(tmp+1, "%.14G", v); - if (strchr(tmp+1, 'E')) - sprintf(tmp+1, "%.9G", v); - if (tmp[14] == '.') - tmp[14] = 0; - } - else - { - static char tohex[] = "0123456789ABCDEF"; - long long ll = (long long)v; - char *revptr; - tp = tmp+1; - if (base == 16) - { - *tp++ = '0'; - *tp++ = 'x'; - } - else if (base == 8) - *tp++ = '0'; - - revptr = tp; - do { - *tp++ = tohex[ll%base]; - ll /= base; - } while (ll); - *tp-- = 0; - while (revptr < tp) { - char t = *revptr; - *revptr = *tp; - *tp = t; - tp--; - revptr++; - } - } - - cp = commas+40; - tp = tmp+strlen(tmp); - dp = strchr(tmp, '.'); - if (dp == 0) - dp = tp; - - *--cp = 0; - while (tp>=tmp) - { - *--cp = *tp--; - switch (base) - { - case 10: - if (isdigit(cp[0]) && isdigit(cp[1]) && isdigit(cp[2]) && tp<dp - && tp>=tmp && isdigit(*tp)) - *--cp = ','; - break; - case 16: - if (isxdigit(cp[0]) && isxdigit(cp[1]) - && isxdigit(cp[2]) && isxdigit(cp[3]) - && tp>=tmp && isxdigit(*tp)) - *--cp = ','; - break; - } - } - - if (strlen(cp) > 15) - set_string(tmp); - else - set_string(cp); +void show_value() { + char tmp[25], *tp; + char commas[40], *cp, *dp; + double v = value; + + if(!number_is_ok(value)) { + set_string("Err"); + bell(); + showing_err = 1; + saved = value = 0; /* so it doesn't get saved on exit! */ + return; + } + + if(base == 2) { + int q = (long long)v & 0xffffffffL; + set_bits(q); + return; + } + + tmp[0] = ' '; + if(v < 0) { + tmp[0] = '-'; + v = -v; + } + + if(base == 10) { + sprintf(tmp + 1, "%.14G", v); + if(strchr(tmp + 1, 'E')) + sprintf(tmp + 1, "%.9G", v); + if(tmp[14] == '.') + tmp[14] = 0; + } else { + static char tohex[] = "0123456789ABCDEF"; + long long ll = (long long)v; + char *revptr; + tp = tmp + 1; + if(base == 16) { + *tp++ = '0'; + *tp++ = 'x'; + } else if(base == 8) + *tp++ = '0'; + + revptr = tp; + do { + *tp++ = tohex[ll % base]; + ll /= base; + } while(ll); + *tp-- = 0; + while(revptr < tp) { + char t = *revptr; + *revptr = *tp; + *tp = t; + tp--; + revptr++; + } + } + + cp = commas + 40; + tp = tmp + strlen(tmp); + dp = strchr(tmp, '.'); + if(dp == 0) + dp = tp; + + *--cp = 0; + while(tp >= tmp) { + *--cp = *tp--; + switch (base) { + case 10: + if(isdigit(cp[0]) && isdigit(cp[1]) && isdigit(cp[2]) + && tp < dp && tp >= tmp && isdigit(*tp)) + *--cp = ','; + break; + case 16: + if(isxdigit(cp[0]) && isxdigit(cp[1]) + && isxdigit(cp[2]) && isxdigit(cp[3]) + && tp >= tmp && isxdigit(*tp)) + *--cp = ','; + break; + } + } + + if(strlen(cp) > 15) + set_string(tmp); + else + set_string(cp); } -void -end_number() -{ - if (!making_number) - return; - making_number = 0; - iptr = 0; - - switch (pending_op) - { - case '+': - value = saved + value; - break; - case '-': - value = saved - value; - break; - case '*': - value = saved * value; - break; - case '/': - value = saved / value; - break; - case '%': - value = (long long)saved % (long long)value; - break; - case '&': - value = (long long)saved & (long long)value; - break; - case '|': - value = (long long)saved | (long long)value; - break; - case '^': - value = (long long)saved ^ (long long)value; - break; - case 'S': /* Shift. Positive means <<, negative means >> */ - if (value < 0) - value = (long long)saved >> (long long)(-value); - else - value = (long long)saved << (long long)value; - break; - } - saved = value; - pending_op = 0; - show_value(); +void end_number() { + if(!making_number) + return; + making_number = 0; + iptr = 0; + + switch (pending_op) { + case '+': + value = saved + value; + break; + case '-': + value = saved - value; + break; + case '*': + value = saved * value; + break; + case '/': + value = saved / value; + break; + case '%': + value = (long long)saved % (long long)value; + break; + case '&': + value = (long long)saved & (long long)value; + break; + case '|': + value = (long long)saved | (long long)value; + break; + case '^': + value = (long long)saved ^ (long long)value; + break; + case 'S': /* Shift. Positive means <<, negative means >> */ + if(value < 0) + value = (long long)saved >> (long long)(-value); + else + value = (long long)saved << (long long)value; + break; + } + saved = value; + pending_op = 0; + show_value(); } -void -start_number() -{ - if (making_number) - return; +void start_number() { + if(making_number) + return; - iptr = 1; - input_buf[0] = ' '; - input_buf[1] = 0; - making_number = 1; + iptr = 1; + input_buf[0] = ' '; + input_buf[1] = 0; + making_number = 1; } -void -key(char c) -{ - int v = c; - /* printf("key_number 0x%x\n", v); */ - - if(showing_err) { - switch(c) { - /* list the keys that should be still active in error state */ - case 27: - case 'C': - case 'Q': - case 17: - break; - default: - bell(); - return; - } - } - - switch (c) - { - case 27: - case 'C': - showing_err = 0; - making_number = 0; - iptr = 0; - pending_op = 0; - value = saved = 0; - set_string(""); - show_value(); - break; - case 'u': - if (making_number) - { - making_number = 0; - set_string(""); - } - break; - - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - v = c - 39; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - v -= '0'; - if (v >= base || iptr == MAXIN-1) - bell(); - else - { - start_number(); - input_buf[iptr++] = c; - input_buf[iptr] = 0; - convert_number(); - show_value(); - } - break; - case '.': - if (strchr(input_buf, '.')) - { - bell(); - break; - } - case ',': - if (iptr == 1 || iptr == MAXIN-1) - bell(); - else - { - start_number(); - input_buf[iptr++] = c; - input_buf[iptr] = 0; - convert_number(); - show_value(); - } - break; - - case 8: - case 127: - if (iptr <= 1) - bell(); - else - { - input_buf[--iptr] = 0; - convert_number(); - show_value(); - } - break; - - case '_': /* The +/- key */ - case 'i': - if (making_number) - { - if (input_buf[0] == '-') - input_buf[0] = ' '; - else - input_buf[0] = '-'; - convert_number(); - show_value(); - } - else - { - value *= -1.0; - saved *= -1.0; - show_value(); - } - break; - - case 'D': - end_number(); - base = 10; - show_value(); - break; - case 'H': - end_number(); - base = 16; - show_value(); - break; - case 'O': - end_number(); - base = 8; - show_value(); - break; - case 'B': - end_number(); - base = 2; - show_value(); - break; - - case 'x': /* Allow 'x' on keyboard to be used to enter '*' */ - c = '*'; - case '+': - case '-': - case '*': - case '/': - case '%': - case '^': - case '&': - case '|': - case 'S': - case '=': - end_number(); - pending_op = c; - break; - - case 13: - case 10: - end_number(); - pending_op = '='; - break; - - case '~': /* Invert bits (one's complement) */ - end_number(); - value = ~ (long long)value; - saved = value; - show_value(); - break; - - case '@': /* Two's complement */ - end_number(); - { - unsigned int i = ((unsigned int)value) & 0xffffffff; - value = ~i + 1; - } - saved = value; - show_value(); - break; - - case '<': /* SHL by one bit only */ -/* Modified by Keith Meehl to fix bit shift bug*/ - end_number(); - value = (long long)value << 1; - saved = value; - pending_op = 0; - show_value(); - break; - - case '>': /* SHR by one bit only */ -/* Modified by Keith Meehl to fix bit shift bug*/ - end_number(); - value = (long long)value >> 1; - saved = value; - pending_op = 0; - show_value(); - break; - - case '[': /* STO */ - stored = value; - break; - case ']': /* RCL */ - value = stored; - show_value(); - making_number = 1; - iptr = 1; - input_buf[0] = ' '; - break; - case '}': /* SUM */ - stored += value; - break; - - case 'P': /* click on the display itself */ - break; - - case 3: /* ^C */ - copy(); - break; - - case 22: /* ^V */ - paste(); - break; - - case 'q': - quiet = !quiet; - break; - - case 'Q': - case 17: - exit(0); - - case 'z': - { - /* dirty hack method of changing window size: - re-execute ourselves with appropriate argument. - TODO: see if this leaks memory, fds, etc */ - extern char *self; - char *args[4]; - - args[0] = self; - - switch(winsize) { - case 0: - args[1] = "-medium"; - break; - case 1: - args[1] = "-large"; - break; - case 2: - args[1] = "-small"; +void key(char c) { + int v = c; + /* printf("key_number 0x%x\n", v); */ + + if(showing_err) { + switch (c) { + /* list the keys that should be still active in error state */ + case 27: + case 'C': + case 'Q': + case 17: break; + default: + bell(); + return; } - - args[2] = NULL; - - /* note that atexit() functions do NOT get called on execv() */ - save_config(); - - XCloseDisplay(display); - - execv(self, args); - } - } + } + + switch (c) { + case 27: + case 'C': + showing_err = 0; + making_number = 0; + iptr = 0; + pending_op = 0; + value = saved = 0; + set_string(""); + show_value(); + break; + case 'u': + if(making_number) { + making_number = 0; + set_string(""); + } + break; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + v = c - 39; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + v -= '0'; + if(v >= base || iptr == MAXIN - 1) + bell(); + else { + start_number(); + input_buf[iptr++] = c; + input_buf[iptr] = 0; + convert_number(); + show_value(); + } + break; + case '.': + if(strchr(input_buf, '.')) { + bell(); + break; + } + case ',': + if(iptr == 1 || iptr == MAXIN - 1) + bell(); + else { + start_number(); + input_buf[iptr++] = c; + input_buf[iptr] = 0; + convert_number(); + show_value(); + } + break; + + case 8: + case 127: + if(iptr <= 1) + bell(); + else { + input_buf[--iptr] = 0; + convert_number(); + show_value(); + } + break; + + case '_': /* The +/- key */ + case 'i': + if(making_number) { + if(input_buf[0] == '-') + input_buf[0] = ' '; + else + input_buf[0] = '-'; + convert_number(); + show_value(); + } else { + value *= -1.0; + saved *= -1.0; + show_value(); + } + break; + + case 'D': + end_number(); + base = 10; + show_value(); + break; + case 'H': + end_number(); + base = 16; + show_value(); + break; + case 'O': + end_number(); + base = 8; + show_value(); + break; + case 'B': + end_number(); + base = 2; + show_value(); + break; + + case 'x': /* Allow 'x' on keyboard to be used to enter '*' */ + c = '*'; + case '+': + case '-': + case '*': + case '/': + case '%': + case '^': + case '&': + case '|': + case 'S': + case '=': + end_number(); + pending_op = c; + break; + + case 13: + case 10: + end_number(); + pending_op = '='; + break; + + case '~': /* Invert bits (one's complement) */ + end_number(); + value = ~(long long)value; + saved = value; + show_value(); + break; + + case '@': /* Two's complement */ + end_number(); + { + unsigned int i = ((unsigned int)value) & 0xffffffff; + value = ~i + 1; + } + saved = value; + show_value(); + break; + + case '<': /* SHL by one bit only */ +/* Modified by Keith Meehl to fix bit shift bug*/ + end_number(); + value = (long long)value << 1; + saved = value; + pending_op = 0; + show_value(); + break; + + case '>': /* SHR by one bit only */ +/* Modified by Keith Meehl to fix bit shift bug*/ + end_number(); + value = (long long)value >> 1; + saved = value; + pending_op = 0; + show_value(); + break; + + case '[': /* STO */ + stored = value; + break; + case ']': /* RCL */ + value = stored; + show_value(); + making_number = 1; + iptr = 1; + input_buf[0] = ' '; + break; + case '}': /* SUM */ + stored += value; + break; + + case 'P': /* click on the display itself */ + break; + + case 3: /* ^C */ + copy(); + break; + + case 22: /* ^V */ + paste(); + break; + + case 'q': + quiet = !quiet; + break; + + case 'Q': + case 17: + exit(0); + + case 'z': + { + /* dirty hack method of changing window size: + re-execute ourselves with appropriate argument. + TODO: see if this leaks memory, fds, etc */ + extern char *self; + char *args[4]; + + args[0] = self; + + switch (winsize) { + case 0: + args[1] = "-medium"; + break; + case 1: + args[1] = "-large"; + break; + case 2: + args[1] = "-small"; + break; + } + + args[2] = NULL; + + /* note that atexit() functions do NOT get called on execv() */ + save_config(); + + XCloseDisplay(display); + + execv(self, args); + } + } } static char *bmap[] = { - "PPPP\033", /* mouse copy and paste, CLR */ - "DHOB\010", /* DEC, HEX, OCT, BIN, DEL */ - "[]}<>", /* STO, RCL, SUM, <<, >> */ - "Sdef/", /* SHF, D E F / */ - "~abc*", /* INV, */ - "|789-", /* OR, */ - "&456+", /* AND, */ - "^123=", /* XOR, */ - "u0._=" /* CE, 0, . , +/-, = */ + "PPPP\033", /* mouse copy and paste, CLR */ + "DHOB\010", /* DEC, HEX, OCT, BIN, DEL */ + "[]}<>", /* STO, RCL, SUM, <<, >> */ + "Sdef/", /* SHF, D E F / */ + "~abc*", /* INV, */ + "|789-", /* OR, */ + "&456+", /* AND, */ + "^123=", /* XOR, */ + "u0._=" /* CE, 0, . , +/-, = */ }; -void -copy(void) -{ - XSetSelectionOwner(display, XA_PRIMARY, window, event.xbutton.time); +void copy(void) { + XSetSelectionOwner(display, XA_PRIMARY, window, event.xbutton.time); } -void -paste(void) -{ - XConvertSelection(display, XA_PRIMARY, XA_STRING, paste_atom, window, - event.xbutton.time); +void paste(void) { + XConvertSelection(display, XA_PRIMARY, XA_STRING, paste_atom, window, + event.xbutton.time); } -void -complete_paste(unsigned char *s, int n) -{ - int i; - for (i=0; i<n; i++) - key(s[i]); - +void complete_paste(unsigned char *s, int n) { + int i; + for(i = 0; i < n; i++) + key(s[i]); + } -void -button(int b, int x, int y) -{ - char k; - - if(b == 2) { - paste(); - return; - } - - x = (x-2)/(24 * scale_factor); - if (x < 0) x = 0; - if (x > 4) x = 4; - y = (y-1)/(16 * scale_factor); - if (y < 0) y = 0; - if (y > 8) y = 8; - - k = bmap[y][x]; - - if (k == 27 && b == 3) - exit(0); - - if (k == 'P' && b == 1) - copy(); - else if (k == 'P' && b != 1) - paste(); - else if(k == '/' && b != 1) - key('%'); - else if(k == '~' && b != 1) - key('@'); - else - key(k); +void button(int b, int x, int y) { + char k; + + if(b == 2) { + paste(); + return; + } + + x = (x - 2) / (24 * scale_factor); + if(x < 0) + x = 0; + if(x > 4) + x = 4; + y = (y - 1) / (16 * scale_factor); + if(y < 0) + y = 0; + if(y > 8) + y = 8; + + k = bmap[y][x]; + + if(k == 27 && b == 3) + exit(0); + + if(k == 'P' && b == 1) + copy(); + else if(k == 'P' && b != 1) + paste(); + else if(k == '/' && b != 1) + key('%'); + else if(k == '~' && b != 1) + key('@'); + else + key(k); } |