X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=tack%2Fscan.c;fp=tack%2Fscan.c;h=d9429c96ee5a80f54f61e4b687d66f35adc172c7;hp=0000000000000000000000000000000000000000;hb=0eb88fc5281804773e2a0c7a488a4452463535ce;hpb=661078ddbde3ce0f3b06e95642fbb9b5fef7dca1 diff --git a/tack/scan.c b/tack/scan.c new file mode 100644 index 00000000..d9429c96 --- /dev/null +++ b/tack/scan.c @@ -0,0 +1,261 @@ +/* +** Copyright (C) 1991, 1997 Free Software Foundation, Inc. +** +** This file is part of TACK. +** +** TACK is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2, or (at your option) +** any later version. +** +** TACK is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with TACK; see the file COPYING. If not, write to +** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +*/ +/* scan mode keyboard support */ + +#include + +MODULE_ID("$Id: scan.c,v 1.2 1999/08/21 23:09:35 tom Exp $") + +int scan_max; /* length of longest scan code */ +char **scan_up, **scan_down, **scan_name; +int *scan_tested, *scan_length, *scan_value; + +static int shift_state; +static char *str; +static int debug_char_count; + +#define SHIFT_KEY 0x100 +#define CONTROL_KEY 0x200 +#define META_KEY 0x400 +#define CAPS_LOCK 0x800 + +static const struct { + const char *name; + int type; +} scan_special[] = { + {"", SHIFT_KEY}, + {"", SHIFT_KEY}, + {"", SHIFT_KEY}, + {"", CONTROL_KEY}, + {"", CONTROL_KEY}, + {"", CONTROL_KEY}, + {"", META_KEY}, + {"", META_KEY}, + {"", META_KEY}, + {"", CAPS_LOCK}, + {"", '\t'}, + {"", ' '}, + {"", '\r'}, + {"", '\n'}, + {"", '\f'}, + {"", '\b'}, + {0, 0} +}; + +static void +scan_blanks(void) +{ /* scan past the white space */ + while (*str == ' ' || *str == '\t') + str++; +} + +static char * +smash(void) +{ /* convert a string to hex */ + char *s, *t; + int ch, i, j; + + t = s = str; + for (i = 0; (ch = *str); str++) { + if (ch >= '0' && ch <= '9') + j = ch - '0'; + else if (ch >= 'a' && ch <= 'f') + j = 10 - 'a' + ch; + else if (ch >= 'A' && ch <= 'F') + j = 10 - 'A' + ch; + else if (ch == ' ' || ch == '\t') + break; + else + continue; + if (i) { + *s |= j; + s++; + } else + *s = j << 4; + i ^= 1; + } + *s = '\0'; + return t; +} + +void +scan_init(char *fn) +{ /* read the scan mode key definitions */ + char *s, *sl; + FILE *fp; + int ch, i, j; + char home[512]; + + if ((str = getenv("HOME"))) + strcpy(home, str); + else + home[0] = '\0'; + fp = NULL; + if ((str = getenv("KEYBOARD"))) { + if (!(fp = fopen(str, "r")) && home[0]) { + sprintf(temp, "%s/.scan.%s", home, str); + fp = fopen(temp, "r"); + } + } + if (!fp) { + sprintf(temp, ".scan.%s", fn); + fp = fopen(temp, "r"); + } + if (!fp && home[0]) { + sprintf(temp, "%s/.scan.%s", home, fn); + fp = fopen(temp, "r"); + } + if (!fp) { + ptext("Unable to open scanfile: "); + ptextln(temp); + bye_kids(1); + return; + } + /* + scan file format: + + + + values are in hex. may be any string of characters + + */ + scan_up = (char **) malloc(sizeof(char *) * MAX_SCAN); + scan_down = (char **) malloc(sizeof(char *) * MAX_SCAN); + scan_name = (char **) malloc(sizeof(char *) * MAX_SCAN); + scan_tested = (int *) malloc(sizeof(int *) * MAX_SCAN); + scan_length = (int *) malloc(sizeof(int *) * MAX_SCAN); + scan_value = (int *) malloc(sizeof(int *) * MAX_SCAN); + scan_up[0] = scan_down[0] = scan_name[0] = (char *) 0; + str = (char *) malloc(4096); /* buffer space */ + sl = str + 4000; /* an upper limit */ + scan_max = 1; + for (i = 0;;) { + for (s = str; (ch = getc(fp)) != EOF;) { + if (ch == '\n' || ch == '\r') + break; + *s++ = ch; + } + *s++ = '\0'; + if (ch == EOF) + break; + if (*str == '#' || *str == '\0') + continue; + scan_down[i] = smash(); + scan_blanks(); + scan_up[i] = smash(); + scan_blanks(); + scan_name[i] = str; + + scan_length[i] = strlen(scan_down[i]); + ch = strlen(scan_up[i]) + scan_length[i]; + if (ch > scan_max) + scan_max = ch; + + scan_value[i] = scan_name[i][0]; + if (scan_name[i][1]) /* multi-character name */ + for (j = 0; scan_special[j].name; j++) { + if (!strcmp(scan_name[i], scan_special[j].name)) { + scan_value[i] = scan_special[j].type; + break; + } + } + + i++; + if (str > sl) { + str = (char *) malloc(4096); + sl = str + 4000; + } else + str = s; + } + fclose(fp); +#ifdef notdef + for (i = 0; scan_down[i]; i++) { + put_str(hex_expand_to(scan_down[i], 3)); + put_str(hex_expand_to(scan_up[i], 3)); + put_str(" "); + put_str(scan_name[i]); + put_crlf(); + } + (void) wait_here(); +#endif +} + +int +scan_key(void) +{ /* read a key and translate scan mode to + ASCII */ + int i, j, ch; + char buf[64]; + + for (i = 1;; i++) { + ch = getchar(); + if (ch == EOF) + return EOF; + if (debug_fp) { + fprintf(debug_fp, "%02X ", ch); + debug_char_count += 3; + if (debug_char_count > 72) { + fprintf(debug_fp, "\n"); + debug_char_count = 0; + } + } + buf[i - 1] = ch; + buf[i] = '\0'; + if (buf[0] & 0x80) { /* scan up */ + for (j = 0; scan_up[j]; j++) { + if (i == scan_length[j] && + !strcmp(buf, scan_up[j])) { + i = 0; + shift_state &= ~scan_value[j]; + break; + } + } + continue; + } + for (j = 0; scan_down[j]; j++) { + if (i == scan_length[j] && !strcmp(buf, scan_down[j])) { + i = 0; + shift_state |= scan_value[j]; + ch = scan_value[j]; + if (ch == CAPS_LOCK) + shift_state ^= SHIFT_KEY; + if (ch >= 256) + break; + if (shift_state & SHIFT_KEY) { + if (ch >= 0x60) + ch -= 0x20; + else if (ch >= 0x30 && ch <= 0x3f) + ch -= 0x10; + } + if (shift_state & CONTROL_KEY) { + if ((ch | 0x20) >= 0x60 && + (ch | 0x20) <= 0x7f) + ch = (ch | 0x20) - 0x60; + } + if (shift_state & META_KEY) + ch |= 0x80; + return ch; + } + } + if (i > scan_max) + i = 1; + } +}