source: trunk/essentials/sys-libs/ncurses/tack/scan.c

Last change on this file was 2621, checked in by bird, 19 years ago

GNU ncurses 5.5

File size: 5.8 KB
Line 
1/*
2** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
3**
4** This file is part of TACK.
5**
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)
9** any later version.
10**
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.
15**
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
20*/
21/* scan mode keyboard support */
22
23#include <tack.h>
24
25MODULE_ID("$Id: scan.c,v 1.5 2005/09/17 19:49:16 tom Exp $")
26
27unsigned scan_max; /* length of longest scan code */
28char **scan_up, **scan_down, **scan_name;
29unsigned *scan_tested, *scan_length;
30static unsigned *scan_value;
31
32static int shift_state;
33static char *str;
34static int debug_char_count;
35
36#define SHIFT_KEY 0x100
37#define CONTROL_KEY 0x200
38#define META_KEY 0x400
39#define CAPS_LOCK 0x800
40
41static const struct {
42 const char *name;
43 unsigned type;
44} scan_special[] = {
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},
51 {"<meta>", META_KEY},
52 {"<left meta>", META_KEY},
53 {"<right meta>", META_KEY},
54 {"<caps lock>", CAPS_LOCK},
55 {"<tab>", '\t'},
56 {"<space>", ' '},
57 {"<return>", '\r'},
58 {"<linefeed>", '\n'},
59 {"<formfeed>", '\f'},
60 {"<backspace>", '\b'},
61 {0, 0}
62};
63
64static void
65scan_blanks(void)
66{ /* scan past the white space */
67 while (*str == ' ' || *str == '\t')
68 str++;
69}
70
71static char *
72smash(void)
73{ /* convert a string to hex */
74 char *s, *t;
75 int ch, i, j;
76
77 t = s = str;
78 for (i = 0; (ch = *str); str++) {
79 if (ch >= '0' && ch <= '9')
80 j = ch - '0';
81 else if (ch >= 'a' && ch <= 'f')
82 j = 10 - 'a' + ch;
83 else if (ch >= 'A' && ch <= 'F')
84 j = 10 - 'A' + ch;
85 else if (ch == ' ' || ch == '\t')
86 break;
87 else
88 continue;
89 if (i) {
90 *s |= j;
91 s++;
92 } else
93 *s = j << 4;
94 i ^= 1;
95 }
96 *s = '\0';
97 return t;
98}
99
100void
101scan_init(char *fn)
102{ /* read the scan mode key definitions */
103 char *s, *sl;
104 FILE *fp;
105 int ch, i, j;
106 unsigned len;
107 char home[512];
108
109 if ((str = getenv("HOME")))
110 strcpy(home, str);
111 else
112 home[0] = '\0';
113 fp = NULL;
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");
118 }
119 }
120 if (!fp) {
121 sprintf(temp, ".scan.%s", fn);
122 fp = fopen(temp, "r");
123 }
124 if (!fp && home[0]) {
125 sprintf(temp, "%s/.scan.%s", home, fn);
126 fp = fopen(temp, "r");
127 }
128 if (!fp) {
129 ptext("Unable to open scanfile: ");
130 ptextln(temp);
131 bye_kids(1);
132 return;
133 }
134 /*
135 scan file format:
136
137 <down value> <up value> <name>
138
139 values are in hex. <name> may be any string of characters
140
141 */
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 */
151 scan_max = 1;
152 for (i = 0;;) {
153 for (s = str; (ch = getc(fp)) != EOF;) {
154 if (ch == '\n' || ch == '\r')
155 break;
156 *s++ = ch;
157 }
158 *s++ = '\0';
159 if (ch == EOF)
160 break;
161 if (*str == '#' || *str == '\0')
162 continue;
163 scan_down[i] = smash();
164 scan_blanks();
165 scan_up[i] = smash();
166 scan_blanks();
167 scan_name[i] = str;
168
169 scan_length[i] = strlen(scan_down[i]);
170 len = strlen(scan_up[i]) + scan_length[i];
171 if (len > scan_max)
172 scan_max = len;
173
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;
179 break;
180 }
181 }
182
183 i++;
184 if (str > sl) {
185 str = (char *) malloc(4096);
186 sl = str + 4000;
187 } else
188 str = s;
189 }
190 fclose(fp);
191#ifdef notdef
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));
195 put_str(" ");
196 put_str(scan_name[i]);
197 put_crlf();
198 }
199 (void) wait_here();
200#endif
201}
202
203int
204scan_key(void)
205{ /* read a key and translate scan mode to
206 ASCII */
207 unsigned i;
208 int j, ch;
209 char buf[64];
210
211 for (i = 1;; i++) {
212 ch = getchar();
213 if (ch == EOF)
214 return EOF;
215 if (debug_fp) {
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;
221 }
222 }
223 buf[i - 1] = ch;
224 buf[i] = '\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])) {
229 i = 0;
230 shift_state &= ~scan_value[j];
231 break;
232 }
233 }
234 continue;
235 }
236 for (j = 0; scan_down[j]; j++) {
237 if (i == scan_length[j] && !strcmp(buf, scan_down[j])) {
238 i = 0;
239 shift_state |= scan_value[j];
240 ch = scan_value[j];
241 if (ch == CAPS_LOCK)
242 shift_state ^= SHIFT_KEY;
243 if (ch >= 256)
244 break;
245 if (shift_state & SHIFT_KEY) {
246 if (ch >= 0x60)
247 ch -= 0x20;
248 else if (ch >= 0x30 && ch <= 0x3f)
249 ch -= 0x10;
250 }
251 if (shift_state & CONTROL_KEY) {
252 if ((ch | 0x20) >= 0x60 &&
253 (ch | 0x20) <= 0x7f)
254 ch = (ch | 0x20) - 0x60;
255 }
256 if (shift_state & META_KEY)
257 ch |= 0x80;
258 return ch;
259 }
260 }
261 if (i > scan_max)
262 i = 1;
263 }
264}
Note: See TracBrowser for help on using the repository browser.