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., 51 Franklin Street, Fifth Floor,
19 ** Boston, MA 02110-1301, USA
21 /* scan mode keyboard support */
25 MODULE_ID("$Id: scan.c,v 1.5 2005/09/17 19:49:16 tom Exp $")
27 unsigned scan_max; /* length of longest scan code */
28 char **scan_up, **scan_down, **scan_name;
29 unsigned *scan_tested, *scan_length;
30 static unsigned *scan_value;
32 static int shift_state;
34 static int debug_char_count;
36 #define SHIFT_KEY 0x100
37 #define CONTROL_KEY 0x200
38 #define META_KEY 0x400
39 #define CAPS_LOCK 0x800
45 {"<shift>", SHIFT_KEY},
46 {"<left shift>", SHIFT_KEY},
47 {"<right shift>", SHIFT_KEY},
48 {"<control>", CONTROL_KEY},
49 {"<left control>", CONTROL_KEY},
50 {"<right control>", CONTROL_KEY},
52 {"<left meta>", META_KEY},
53 {"<right meta>", META_KEY},
54 {"<caps lock>", CAPS_LOCK},
60 {"<backspace>", '\b'},
66 { /* scan past the white space */
67 while (*str == ' ' || *str == '\t')
73 { /* convert a string to hex */
78 for (i = 0; (ch = *str); str++) {
79 if (ch >= '0' && ch <= '9')
81 else if (ch >= 'a' && ch <= 'f')
83 else if (ch >= 'A' && ch <= 'F')
85 else if (ch == ' ' || ch == '\t')
102 { /* read the scan mode key definitions */
109 if ((str = getenv("HOME")))
114 if ((str = getenv("KEYBOARD"))) {
115 if (!(fp = fopen(str, "r")) && home[0]) {
116 sprintf(temp, "%s/.scan.%s", home, str);
117 fp = fopen(temp, "r");
121 sprintf(temp, ".scan.%s", fn);
122 fp = fopen(temp, "r");
124 if (!fp && home[0]) {
125 sprintf(temp, "%s/.scan.%s", home, fn);
126 fp = fopen(temp, "r");
129 ptext("Unable to open scanfile: ");
137 <down value> <up value> <name>
139 values are in hex. <name> may be any string of characters
142 scan_up = (char **) malloc(sizeof(char *) * MAX_SCAN);
143 scan_down = (char **) malloc(sizeof(char *) * MAX_SCAN);
144 scan_name = (char **) malloc(sizeof(char *) * MAX_SCAN);
145 scan_tested = (unsigned *) malloc(sizeof(unsigned *) * MAX_SCAN);
146 scan_length = (unsigned *) malloc(sizeof(unsigned *) * MAX_SCAN);
147 scan_value = (unsigned *) malloc(sizeof(unsigned *) * MAX_SCAN);
148 scan_up[0] = scan_down[0] = scan_name[0] = (char *) 0;
149 str = (char *) malloc(4096); /* buffer space */
150 sl = str + 4000; /* an upper limit */
153 for (s = str; (ch = getc(fp)) != EOF;) {
154 if (ch == '\n' || ch == '\r')
161 if (*str == '#' || *str == '\0')
163 scan_down[i] = smash();
165 scan_up[i] = smash();
169 scan_length[i] = strlen(scan_down[i]);
170 len = strlen(scan_up[i]) + scan_length[i];
174 scan_value[i] = UChar(scan_name[i][0]);
175 if (scan_name[i][1]) /* multi-character name */
176 for (j = 0; scan_special[j].name; j++) {
177 if (!strcmp(scan_name[i], scan_special[j].name)) {
178 scan_value[i] = scan_special[j].type;
185 str = (char *) malloc(4096);
192 for (i = 0; scan_down[i]; i++) {
193 put_str(hex_expand_to(scan_down[i], 3));
194 put_str(hex_expand_to(scan_up[i], 3));
196 put_str(scan_name[i]);
205 { /* read a key and translate scan mode to
216 fprintf(debug_fp, "%02X ", ch);
217 debug_char_count += 3;
218 if (debug_char_count > 72) {
219 fprintf(debug_fp, "\n");
220 debug_char_count = 0;
225 if (buf[0] & 0x80) { /* scan up */
226 for (j = 0; scan_up[j]; j++) {
227 if (i == scan_length[j] &&
228 !strcmp(buf, scan_up[j])) {
230 shift_state &= ~scan_value[j];
236 for (j = 0; scan_down[j]; j++) {
237 if (i == scan_length[j] && !strcmp(buf, scan_down[j])) {
239 shift_state |= scan_value[j];
242 shift_state ^= SHIFT_KEY;
245 if (shift_state & SHIFT_KEY) {
248 else if (ch >= 0x30 && ch <= 0x3f)
251 if (shift_state & CONTROL_KEY) {
252 if ((ch | 0x20) >= 0x60 &&
254 ch = (ch | 0x20) - 0x60;
256 if (shift_state & META_KEY)