2 ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
4 ** This file is part of TACK.
6 ** TACK 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 ** TACK is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
16 ** You should have received a copy of the GNU General Public License
17 ** along with TACK; see the file COPYING. If not, write to
18 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 ** Boston, MA 02111-1307, USA.
21 /* scan mode keyboard support */
25 MODULE_ID("$Id: scan.c,v 1.2 1999/08/21 23:09:35 tom Exp $")
27 int scan_max; /* length of longest scan code */
28 char **scan_up, **scan_down, **scan_name;
29 int *scan_tested, *scan_length, *scan_value;
31 static int shift_state;
33 static int debug_char_count;
35 #define SHIFT_KEY 0x100
36 #define CONTROL_KEY 0x200
37 #define META_KEY 0x400
38 #define CAPS_LOCK 0x800
44 {"<shift>", SHIFT_KEY},
45 {"<left shift>", SHIFT_KEY},
46 {"<right shift>", SHIFT_KEY},
47 {"<control>", CONTROL_KEY},
48 {"<left control>", CONTROL_KEY},
49 {"<right control>", CONTROL_KEY},
51 {"<left meta>", META_KEY},
52 {"<right meta>", META_KEY},
53 {"<caps lock>", CAPS_LOCK},
59 {"<backspace>", '\b'},
65 { /* scan past the white space */
66 while (*str == ' ' || *str == '\t')
72 { /* convert a string to hex */
77 for (i = 0; (ch = *str); str++) {
78 if (ch >= '0' && ch <= '9')
80 else if (ch >= 'a' && ch <= 'f')
82 else if (ch >= 'A' && ch <= 'F')
84 else if (ch == ' ' || ch == '\t')
101 { /* read the scan mode key definitions */
107 if ((str = getenv("HOME")))
112 if ((str = getenv("KEYBOARD"))) {
113 if (!(fp = fopen(str, "r")) && home[0]) {
114 sprintf(temp, "%s/.scan.%s", home, str);
115 fp = fopen(temp, "r");
119 sprintf(temp, ".scan.%s", fn);
120 fp = fopen(temp, "r");
122 if (!fp && home[0]) {
123 sprintf(temp, "%s/.scan.%s", home, fn);
124 fp = fopen(temp, "r");
127 ptext("Unable to open scanfile: ");
135 <down value> <up value> <name>
137 values are in hex. <name> may be any string of characters
140 scan_up = (char **) malloc(sizeof(char *) * MAX_SCAN);
141 scan_down = (char **) malloc(sizeof(char *) * MAX_SCAN);
142 scan_name = (char **) malloc(sizeof(char *) * MAX_SCAN);
143 scan_tested = (int *) malloc(sizeof(int *) * MAX_SCAN);
144 scan_length = (int *) malloc(sizeof(int *) * MAX_SCAN);
145 scan_value = (int *) malloc(sizeof(int *) * MAX_SCAN);
146 scan_up[0] = scan_down[0] = scan_name[0] = (char *) 0;
147 str = (char *) malloc(4096); /* buffer space */
148 sl = str + 4000; /* an upper limit */
151 for (s = str; (ch = getc(fp)) != EOF;) {
152 if (ch == '\n' || ch == '\r')
159 if (*str == '#' || *str == '\0')
161 scan_down[i] = smash();
163 scan_up[i] = smash();
167 scan_length[i] = strlen(scan_down[i]);
168 ch = strlen(scan_up[i]) + scan_length[i];
172 scan_value[i] = scan_name[i][0];
173 if (scan_name[i][1]) /* multi-character name */
174 for (j = 0; scan_special[j].name; j++) {
175 if (!strcmp(scan_name[i], scan_special[j].name)) {
176 scan_value[i] = scan_special[j].type;
183 str = (char *) malloc(4096);
190 for (i = 0; scan_down[i]; i++) {
191 put_str(hex_expand_to(scan_down[i], 3));
192 put_str(hex_expand_to(scan_up[i], 3));
194 put_str(scan_name[i]);
203 { /* read a key and translate scan mode to
213 fprintf(debug_fp, "%02X ", ch);
214 debug_char_count += 3;
215 if (debug_char_count > 72) {
216 fprintf(debug_fp, "\n");
217 debug_char_count = 0;
222 if (buf[0] & 0x80) { /* scan up */
223 for (j = 0; scan_up[j]; j++) {
224 if (i == scan_length[j] &&
225 !strcmp(buf, scan_up[j])) {
227 shift_state &= ~scan_value[j];
233 for (j = 0; scan_down[j]; j++) {
234 if (i == scan_length[j] && !strcmp(buf, scan_down[j])) {
236 shift_state |= scan_value[j];
239 shift_state ^= SHIFT_KEY;
242 if (shift_state & SHIFT_KEY) {
245 else if (ch >= 0x30 && ch <= 0x3f)
248 if (shift_state & CONTROL_KEY) {
249 if ((ch | 0x20) >= 0x60 &&
251 ch = (ch | 0x20) - 0x60;
253 if (shift_state & META_KEY)