File: | os_tty.c |
Location: | line 2264, column 56 |
Description: | Assigned value is garbage or undefined |
1 | /* File: "os_tty.c" */ | |||
2 | ||||
3 | /* Copyright (c) 1994-2013 by Marc Feeley, All Rights Reserved. */ | |||
4 | ||||
5 | /* | |||
6 | * This module implements the operating system specific routines | |||
7 | * related to ttys. | |||
8 | */ | |||
9 | ||||
10 | #define ___INCLUDED_FROM_OS_TTY | |||
11 | #define ___VERSION407000 407000 | |||
12 | #include "gambit.h" | |||
13 | ||||
14 | #include "os_base.h" | |||
15 | #include "os_tty.h" | |||
16 | #include "os_shell.h" | |||
17 | #include "os_io.h" | |||
18 | #include "setup.h" | |||
19 | #include "c_intf.h" | |||
20 | ||||
21 | ||||
22 | /*---------------------------------------------------------------------------*/ | |||
23 | ||||
24 | /* Extensible string routines */ | |||
25 | ||||
26 | ||||
27 | ___HIDDENstatic ___SCMOBJlong extensible_string_setup | |||
28 | ___P((extensible_string *str,(extensible_string *str, int n) | |||
29 | int n),(extensible_string *str, int n) | |||
30 | (str,(extensible_string *str, int n) | |||
31 | n)(extensible_string *str, int n) | |||
32 | extensible_string *str;(extensible_string *str, int n) | |||
33 | int n;)(extensible_string *str, int n) | |||
34 | { | |||
35 | #define EXTENSIBLE_STRING_INITIAL_BUFFER_SIZE32 32 | |||
36 | ||||
37 | if (n < EXTENSIBLE_STRING_INITIAL_BUFFER_SIZE32) | |||
38 | n = EXTENSIBLE_STRING_INITIAL_BUFFER_SIZE32; | |||
39 | ||||
40 | str->buffer = ___CAST(extensible_string_char*,((extensible_string_char*)(___alloc_mem (n * sizeof (extensible_string_char )))) | |||
41 | ___alloc_mem (n * sizeof (extensible_string_char)))((extensible_string_char*)(___alloc_mem (n * sizeof (extensible_string_char )))); | |||
42 | ||||
43 | if (str->buffer == NULL((void*)0)) | |||
44 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
45 | ||||
46 | str->length = 0; | |||
47 | str->max_length = n; | |||
48 | ||||
49 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
50 | } | |||
51 | ||||
52 | ||||
53 | ___HIDDENstatic void extensible_string_cleanup | |||
54 | ___P((extensible_string *str),(extensible_string *str) | |||
55 | (str)(extensible_string *str) | |||
56 | extensible_string *str;)(extensible_string *str) | |||
57 | { | |||
58 | ___free_mem (str->buffer); | |||
59 | } | |||
60 | ||||
61 | ||||
62 | ___HIDDENstatic ___SCMOBJlong extensible_string_copy | |||
63 | ___P((extensible_string_char *src,(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
64 | int len,(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
65 | extensible_string *dst,(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
66 | int fudge),(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
67 | (src,(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
68 | len,(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
69 | dst,(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
70 | fudge)(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
71 | extensible_string_char *src;(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
72 | int len;(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
73 | extensible_string *dst;(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
74 | int fudge;)(extensible_string_char *src, int len, extensible_string *dst , int fudge) | |||
75 | { | |||
76 | extensible_string_char *buf; | |||
77 | ||||
78 | buf = ___CAST(extensible_string_char*,((extensible_string_char*)(___alloc_mem ((len+fudge) * sizeof (extensible_string_char)))) | |||
79 | ___alloc_mem ((len+fudge) * sizeof (extensible_string_char)))((extensible_string_char*)(___alloc_mem ((len+fudge) * sizeof (extensible_string_char)))); | |||
80 | ||||
81 | if (buf == NULL((void*)0)) | |||
82 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
83 | ||||
84 | dst->buffer = buf; | |||
85 | dst->length = len; | |||
86 | dst->max_length = len+fudge; | |||
87 | ||||
88 | while (len-- > 0) | |||
89 | buf[len] = src[len]; | |||
90 | ||||
91 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
92 | } | |||
93 | ||||
94 | ||||
95 | ___HIDDENstatic ___SCMOBJlong extensible_string_set_length | |||
96 | ___P((extensible_string *str,(extensible_string *str, int len, int fudge) | |||
97 | int len,(extensible_string *str, int len, int fudge) | |||
98 | int fudge),(extensible_string *str, int len, int fudge) | |||
99 | (str,(extensible_string *str, int len, int fudge) | |||
100 | len,(extensible_string *str, int len, int fudge) | |||
101 | fudge)(extensible_string *str, int len, int fudge) | |||
102 | extensible_string *str;(extensible_string *str, int len, int fudge) | |||
103 | int len;(extensible_string *str, int len, int fudge) | |||
104 | int fudge;)(extensible_string *str, int len, int fudge) | |||
105 | { | |||
106 | if (len > str->max_length || 2*len+1 < str->max_length) | |||
107 | { | |||
108 | int i; | |||
109 | int new_max_length = (fudge<0) ? 3*len/2+1 : len+fudge; | |||
110 | extensible_string_char *old_buffer = str->buffer; | |||
111 | extensible_string_char *new_buffer = | |||
112 | ___CAST(extensible_string_char*,((extensible_string_char*)(___alloc_mem (new_max_length * sizeof (extensible_string_char)))) | |||
113 | ___alloc_mem (new_max_length *((extensible_string_char*)(___alloc_mem (new_max_length * sizeof (extensible_string_char)))) | |||
114 | sizeof (extensible_string_char)))((extensible_string_char*)(___alloc_mem (new_max_length * sizeof (extensible_string_char)))); | |||
115 | ||||
116 | if (new_buffer == NULL((void*)0)) | |||
117 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
118 | ||||
119 | i = str->length; | |||
120 | if (i > len) | |||
121 | i = len; | |||
122 | ||||
123 | while (i-- > 0) | |||
124 | new_buffer[i] = old_buffer[i]; | |||
125 | ||||
126 | ___free_mem (old_buffer); | |||
127 | str->buffer = new_buffer; | |||
128 | str->max_length = new_max_length; | |||
129 | } | |||
130 | ||||
131 | str->length = len; | |||
132 | ||||
133 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
134 | } | |||
135 | ||||
136 | ||||
137 | ___HIDDENstatic void extensible_string_delete | |||
138 | ___P((extensible_string *str,(extensible_string *str, int pos, int len) | |||
139 | int pos,(extensible_string *str, int pos, int len) | |||
140 | int len),(extensible_string *str, int pos, int len) | |||
141 | (str,(extensible_string *str, int pos, int len) | |||
142 | pos,(extensible_string *str, int pos, int len) | |||
143 | len)(extensible_string *str, int pos, int len) | |||
144 | extensible_string *str;(extensible_string *str, int pos, int len) | |||
145 | int pos;(extensible_string *str, int pos, int len) | |||
146 | int len;)(extensible_string *str, int pos, int len) | |||
147 | { | |||
148 | int i; | |||
149 | ||||
150 | if (pos < 0) | |||
151 | pos = 0; | |||
152 | else if (pos > str->length) | |||
153 | pos = str->length; | |||
154 | ||||
155 | i = str->length - pos; | |||
156 | if (len < 0) | |||
157 | len = 0; | |||
158 | else if (len > i) | |||
159 | len = i; | |||
160 | ||||
161 | for (i=pos; i<str->length-len; i++) | |||
162 | str->buffer[i] = str->buffer[i+len]; | |||
163 | ||||
164 | str->length -= len; | |||
165 | } | |||
166 | ||||
167 | ||||
168 | ___HIDDENstatic ___SCMOBJlong extensible_string_insert | |||
169 | ___P((extensible_string *str,(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
170 | int pos,(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
171 | int len,(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
172 | extensible_string_char *chars),(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
173 | (str,(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
174 | pos,(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
175 | len,(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
176 | chars)(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
177 | extensible_string *str;(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
178 | int pos;(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
179 | int len;(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
180 | extensible_string_char *chars;)(extensible_string *str, int pos, int len, extensible_string_char *chars) | |||
181 | { | |||
182 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
183 | int i; | |||
184 | ||||
185 | if (len > 0) | |||
186 | { | |||
187 | if (pos < 0) | |||
188 | pos = 0; | |||
189 | else if (pos > str->length) | |||
190 | pos = str->length; | |||
191 | ||||
192 | if ((e = extensible_string_set_length (str, str->length+len, -1)) | |||
193 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
194 | { | |||
195 | for (i=str->length-len-1; i>=pos; i--) | |||
196 | str->buffer[i+len] = str->buffer[i]; | |||
197 | ||||
198 | for (i=len-1; i>=0; i--) | |||
199 | str->buffer[i+pos] = chars[i]; | |||
200 | } | |||
201 | } | |||
202 | ||||
203 | return e; | |||
204 | } | |||
205 | ||||
206 | ||||
207 | ___HIDDENstatic ___SCMOBJlong extensible_string_insert_at_end | |||
208 | ___P((extensible_string *str,(extensible_string *str, int len, extensible_string_char *chars ) | |||
209 | int len,(extensible_string *str, int len, extensible_string_char *chars ) | |||
210 | extensible_string_char *chars),(extensible_string *str, int len, extensible_string_char *chars ) | |||
211 | (str,(extensible_string *str, int len, extensible_string_char *chars ) | |||
212 | len,(extensible_string *str, int len, extensible_string_char *chars ) | |||
213 | chars)(extensible_string *str, int len, extensible_string_char *chars ) | |||
214 | extensible_string *str;(extensible_string *str, int len, extensible_string_char *chars ) | |||
215 | int len;(extensible_string *str, int len, extensible_string_char *chars ) | |||
216 | extensible_string_char *chars;)(extensible_string *str, int len, extensible_string_char *chars ) | |||
217 | { | |||
218 | return extensible_string_insert (str, str->length, len, chars); | |||
219 | } | |||
220 | ||||
221 | ||||
222 | /*---------------------------------------------------------------------------*/ | |||
223 | ||||
224 | /* TTY mode setting */ | |||
225 | ||||
226 | ||||
227 | ___HIDDENstatic ___SCMOBJlong ___device_tty_mode_get | |||
228 | ___P((___device_tty *self),(___device_tty *self) | |||
229 | (self)(___device_tty *self) | |||
230 | ___device_tty *self;)(___device_tty *self) | |||
231 | { | |||
232 | ___device_tty *d = self; | |||
233 | ||||
234 | #ifdef USE_tcgetsetattr | |||
235 | #ifdef USE_fcntl | |||
236 | ||||
237 | #ifdef ___DEBUG_TTY | |||
238 | ||||
239 | ___printf ("tcgetattr d->fd = %d\n", d->fd); | |||
240 | ||||
241 | #endif | |||
242 | ||||
243 | if (tcgetattr (d->fd, &d->initial_termios) < 0 || | |||
244 | (d->initial_flags = fcntl (d->fd, F_GETFL3, 0)) < 0) | |||
245 | return err_code_from_errno ()___err_code_from_errno(); | |||
246 | ||||
247 | #ifdef ___DEBUG_TTY | |||
248 | ||||
249 | ___printf ("___device_tty_mode_get d->fd = %d\n", d->fd); | |||
250 | ___printf (" d->initial_termios.c_iflag = 0x%08x\n", d->initial_termios.c_iflag); | |||
251 | ___printf (" d->initial_termios.c_oflag = 0x%08x\n", d->initial_termios.c_oflag); | |||
252 | ___printf (" d->initial_termios.c_lflag = 0x%08x\n", d->initial_termios.c_lflag); | |||
253 | ||||
254 | #endif | |||
255 | #endif | |||
256 | ||||
257 | #endif | |||
258 | ||||
259 | #ifdef USE_WIN32 | |||
260 | ||||
261 | if (!GetConsoleMode (d->hin, &d->hin_initial_mode) || | |||
262 | !GetConsoleMode (d->hout, &d->hout_initial_mode)) | |||
263 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
264 | ||||
265 | #endif | |||
266 | ||||
267 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
268 | } | |||
269 | ||||
270 | ||||
271 | ___HIDDENstatic ___SCMOBJlong ___device_tty_mode_save | |||
272 | ___P((___device_tty *self),(___device_tty *self) | |||
273 | (self)(___device_tty *self) | |||
274 | ___device_tty *self;)(___device_tty *self) | |||
275 | { | |||
276 | ___device_tty *d = self; | |||
277 | ___SCMOBJlong e; | |||
278 | ||||
279 | if ((e = ___device_tty_mode_get (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
280 | return e; | |||
281 | ||||
282 | d->mode_save_stack_next = ___tty_mod.mode_save_stack; | |||
283 | ___tty_mod.mode_save_stack = d; | |||
284 | ||||
285 | d->stage = TTY_STAGE_MODE_NOT_SET2; | |||
286 | ||||
287 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
288 | } | |||
289 | ||||
290 | ||||
291 | ___HIDDENstatic ___SCMOBJlong ___device_tty_mode_update | |||
292 | ___P((___device_tty *self,(___device_tty *self, int current) | |||
293 | ___BOOL current),(___device_tty *self, int current) | |||
294 | (self,(___device_tty *self, int current) | |||
295 | current)(___device_tty *self, int current) | |||
296 | ___device_tty *self;(___device_tty *self, int current) | |||
297 | ___BOOL current;)(___device_tty *self, int current) | |||
298 | { | |||
299 | ___device_tty *d = self; | |||
300 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
301 | ||||
302 | #ifdef USE_tcgetsetattr | |||
303 | #ifdef USE_fcntl | |||
304 | ||||
305 | { | |||
306 | struct termios new_termios = d->initial_termios; | |||
307 | int new_flags = d->initial_flags; | |||
308 | ||||
309 | #ifdef ___DEBUG_TTY | |||
310 | ||||
311 | ___printf ("tcsetattr d->fd = %d\n", d->fd); | |||
312 | ___printf (" d->lineeditor_mode = %d\n", d->lineeditor_mode); | |||
313 | ___printf (" d->input_allow_special = %d\n", d->input_allow_special); | |||
314 | ___printf (" d->input_echo = %d\n", d->input_echo); | |||
315 | ___printf (" d->input_raw = %d\n", d->input_raw); | |||
316 | ___printf (" d->output_raw = %d\n", d->output_raw); | |||
317 | ___printf (" new_termios.c_iflag = 0x%08x\n", new_termios.c_iflag); | |||
318 | ___printf (" new_termios.c_oflag = 0x%08x\n", new_termios.c_oflag); | |||
319 | ___printf (" new_termios.c_lflag = 0x%08x\n", new_termios.c_lflag); | |||
320 | ||||
321 | #endif | |||
322 | ||||
323 | if (current) | |||
324 | { | |||
325 | if (d->input_allow_special) | |||
326 | { | |||
327 | new_termios.c_iflag |= (IXON0002000); | |||
328 | new_termios.c_lflag |= (IEXTEN0100000 | ISIG0000001); | |||
329 | } | |||
330 | else | |||
331 | { | |||
332 | new_termios.c_iflag &= ~(IXON0002000); | |||
333 | new_termios.c_lflag &= ~(IEXTEN0100000 | ISIG0000001); | |||
334 | } | |||
335 | ||||
336 | if (d->input_raw | |||
337 | #ifdef USE_LINEEDITOR | |||
338 | || d->lineeditor_mode != LINEEDITOR_MODE_DISABLE0 | |||
339 | #endif | |||
340 | ) | |||
341 | { | |||
342 | new_termios.c_iflag &= ~(IMAXBEL0020000 | |||
343 | | ISTRIP0000040 | |||
344 | | ICRNL0000400 | |||
345 | | INLCR0000100 | |||
346 | | IGNCR0000200 | |||
347 | | ICRNL0000400 | |||
348 | | IXON0002000 | |||
349 | | IXOFF0010000 | |||
350 | #ifdef IUCLC0001000 | |||
351 | | IUCLC0001000 | |||
352 | #endif | |||
353 | ); | |||
354 | new_termios.c_iflag &= ~(ICRNL0000400); | |||
355 | new_termios.c_lflag &= ~(ICANON0000002 | ECHO0000010 | ECHOCTL0001000); | |||
356 | ||||
357 | #ifndef _POSIX_VDISABLE'\0' | |||
358 | #define _POSIX_VDISABLE'\0' 0xff | |||
359 | #endif | |||
360 | ||||
361 | #if 0 | |||
362 | new_termios.c_cc[VEOF4] = _POSIX_VDISABLE'\0'; | |||
363 | new_termios.c_cc[VEOL11] = _POSIX_VDISABLE'\0'; | |||
364 | new_termios.c_cc[VEOL216] = _POSIX_VDISABLE'\0'; | |||
365 | new_termios.c_cc[VERASE2] = _POSIX_VDISABLE'\0'; | |||
366 | new_termios.c_cc[VWERASE14] = _POSIX_VDISABLE'\0'; | |||
367 | new_termios.c_cc[VKILL3] = _POSIX_VDISABLE'\0'; | |||
368 | new_termios.c_cc[VREPRINT12] = _POSIX_VDISABLE'\0'; | |||
369 | new_termios.c_cc[VINTR0] = _POSIX_VDISABLE'\0'; | |||
370 | new_termios.c_cc[VQUIT1] = _POSIX_VDISABLE'\0'; | |||
371 | new_termios.c_cc[VSUSP10] = _POSIX_VDISABLE'\0'; | |||
372 | #endif | |||
373 | #ifdef VDSUSP | |||
374 | new_termios.c_cc[VDSUSP] = _POSIX_VDISABLE'\0'; | |||
375 | #endif | |||
376 | #if 0 | |||
377 | new_termios.c_cc[VSTART8] = _POSIX_VDISABLE'\0'; | |||
378 | new_termios.c_cc[VSTOP9] = _POSIX_VDISABLE'\0'; | |||
379 | #endif | |||
380 | #ifdef VLNEXT15 | |||
381 | new_termios.c_cc[VLNEXT15] = _POSIX_VDISABLE'\0'; | |||
382 | #endif | |||
383 | #if 0 | |||
384 | new_termios.c_cc[VDISCARD13] = _POSIX_VDISABLE'\0'; | |||
385 | new_termios.c_cc[VMIN6] = _POSIX_VDISABLE'\0'; | |||
386 | new_termios.c_cc[VTIME5] = _POSIX_VDISABLE'\0'; | |||
387 | new_termios.c_cc[VSTATUS] = _POSIX_VDISABLE'\0'; | |||
388 | #endif | |||
389 | ||||
390 | new_termios.c_cc[VMIN6] = 1; | |||
391 | new_termios.c_cc[VTIME5] = 0; | |||
392 | } | |||
393 | else | |||
394 | { | |||
395 | new_termios.c_iflag |= (ICRNL0000400); | |||
396 | new_termios.c_lflag |= (ICANON0000002 | ECHO0000010 | ECHOCTL0001000); | |||
397 | } | |||
398 | ||||
399 | if (!d->input_echo) | |||
400 | new_termios.c_lflag &= ~(ECHO0000010 | ECHOCTL0001000); | |||
401 | ||||
402 | if (d->output_raw) | |||
403 | new_termios.c_oflag &= ~(OPOST0000001 | ONLCR0000004); | |||
404 | else | |||
405 | new_termios.c_oflag |= (OPOST0000001); | |||
406 | ||||
407 | new_termios.c_iflag |= (IGNBRK0000001 | IGNPAR0000004); | |||
408 | ||||
409 | new_termios.c_cflag &= ~(CSIZE0000060 | PARENB0000400); | |||
410 | ||||
411 | new_termios.c_cflag |= (CS80000060 | CLOCAL0004000 | CREAD0000200); | |||
412 | ||||
413 | if (d->speed != 0) | |||
414 | { | |||
415 | int speed_code = -1; | |||
416 | ||||
417 | switch (d->speed) | |||
418 | { | |||
419 | #ifdef B500000001 | |||
420 | case 50: speed_code = B500000001; break; | |||
421 | #endif | |||
422 | #ifdef B750000002 | |||
423 | case 75: speed_code = B750000002; break; | |||
424 | #endif | |||
425 | #ifdef B1100000003 | |||
426 | case 110: speed_code = B1100000003; break; | |||
427 | #endif | |||
428 | #ifdef B1340000004 | |||
429 | case 134: speed_code = B1340000004; break; | |||
430 | #endif | |||
431 | #ifdef B1500000005 | |||
432 | case 150: speed_code = B1500000005; break; | |||
433 | #endif | |||
434 | #ifdef B2000000006 | |||
435 | case 200: speed_code = B2000000006; break; | |||
436 | #endif | |||
437 | #ifdef B3000000007 | |||
438 | case 300: speed_code = B3000000007; break; | |||
439 | #endif | |||
440 | #ifdef B6000000010 | |||
441 | case 600: speed_code = B6000000010; break; | |||
442 | #endif | |||
443 | #ifdef B12000000011 | |||
444 | case 1200: speed_code = B12000000011; break; | |||
445 | #endif | |||
446 | #ifdef B18000000012 | |||
447 | case 1800: speed_code = B18000000012; break; | |||
448 | #endif | |||
449 | #ifdef B24000000013 | |||
450 | case 2400: speed_code = B24000000013; break; | |||
451 | #endif | |||
452 | #ifdef B48000000014 | |||
453 | case 4800: speed_code = B48000000014; break; | |||
454 | #endif | |||
455 | #ifdef B96000000015 | |||
456 | case 9600: speed_code = B96000000015; break; | |||
457 | #endif | |||
458 | #ifdef B192000000016 | |||
459 | case 19200: speed_code = B192000000016; break; | |||
460 | #endif | |||
461 | #ifdef B384000000017 | |||
462 | case 38400: speed_code = B384000000017; break; | |||
463 | #endif | |||
464 | #ifdef B576000010001 | |||
465 | case 57600: speed_code = B576000010001; break; | |||
466 | #endif | |||
467 | #ifdef B1152000010002 | |||
468 | case 115200: speed_code = B1152000010002; break; | |||
469 | #endif | |||
470 | #ifdef B2304000010003 | |||
471 | case 230400: speed_code = B2304000010003; break; | |||
472 | #endif | |||
473 | #ifdef B4608000010004 | |||
474 | case 460800: speed_code = B4608000010004; break; | |||
475 | #endif | |||
476 | #ifdef B5000000010005 | |||
477 | case 500000: speed_code = B5000000010005; break; | |||
478 | #endif | |||
479 | #ifdef B5760000010006 | |||
480 | case 576000: speed_code = B5760000010006; break; | |||
481 | #endif | |||
482 | #ifdef B9216000010007 | |||
483 | case 921600: speed_code = B9216000010007; break; | |||
484 | #endif | |||
485 | #ifdef B10000000010010 | |||
486 | case 1000000: speed_code = B10000000010010; break; | |||
487 | #endif | |||
488 | #ifdef B11520000010011 | |||
489 | case 1152000: speed_code = B11520000010011; break; | |||
490 | #endif | |||
491 | #ifdef B15000000010012 | |||
492 | case 1500000: speed_code = B15000000010012; break; | |||
493 | #endif | |||
494 | #ifdef B20000000010013 | |||
495 | case 2000000: speed_code = B20000000010013; break; | |||
496 | #endif | |||
497 | #ifdef B25000000010014 | |||
498 | case 2500000: speed_code = B25000000010014; break; | |||
499 | #endif | |||
500 | #ifdef B30000000010015 | |||
501 | case 3000000: speed_code = B30000000010015; break; | |||
502 | #endif | |||
503 | #ifdef B35000000010016 | |||
504 | case 3500000: speed_code = B35000000010016; break; | |||
505 | #endif | |||
506 | #ifdef B40000000010017 | |||
507 | case 4000000: speed_code = B40000000010017; break; | |||
508 | #endif | |||
509 | } | |||
510 | ||||
511 | if (speed_code != -1) | |||
512 | { | |||
513 | cfsetispeed (&new_termios, speed_code); | |||
514 | cfsetospeed (&new_termios, speed_code); | |||
515 | } | |||
516 | } | |||
517 | ||||
518 | new_flags = new_flags | O_NONBLOCK04000; | |||
519 | } | |||
520 | ||||
521 | #ifdef ___DEBUG_TTY | |||
522 | ||||
523 | ___printf (" new_termios.c_iflag = 0x%08x\n", new_termios.c_iflag); | |||
524 | ___printf (" new_termios.c_oflag = 0x%08x\n", new_termios.c_oflag); | |||
525 | ___printf (" new_termios.c_lflag = 0x%08x\n", new_termios.c_lflag); | |||
526 | ||||
527 | #endif | |||
528 | ||||
529 | if (tcsetattr (d->fd, TCSANOW0, &new_termios) < 0 || | |||
530 | fcntl (d->fd, F_SETFL4, new_flags) < 0) | |||
531 | e = err_code_from_errno ()___err_code_from_errno(); | |||
532 | } | |||
533 | ||||
534 | #endif | |||
535 | #endif | |||
536 | ||||
537 | #ifdef USE_WIN32 | |||
538 | ||||
539 | { | |||
540 | DWORD hin_mode = d->hin_initial_mode; | |||
541 | DWORD hout_mode = d->hout_initial_mode; | |||
542 | ||||
543 | if (current) | |||
544 | { | |||
545 | if (d->input_allow_special) | |||
546 | hin_mode |= (ENABLE_PROCESSED_INPUT); | |||
547 | else | |||
548 | hin_mode &= ~(ENABLE_PROCESSED_INPUT); | |||
549 | ||||
550 | #ifndef USE_LINEEDITOR | |||
551 | if (!d->input_raw) | |||
552 | hin_mode |= (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); | |||
553 | else | |||
554 | #endif | |||
555 | hin_mode &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); | |||
556 | ||||
557 | #if 0 | |||
558 | #ifndef USE_LINEEDITOR | |||
559 | if (!d->output_raw) | |||
560 | hout_mode |= (ENABLE_PROCESSED_OUTPUT); | |||
561 | else | |||
562 | #endif | |||
563 | hout_mode &= ~(ENABLE_PROCESSED_OUTPUT); | |||
564 | #endif | |||
565 | ||||
566 | hout_mode |= (ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_PROCESSED_OUTPUT); | |||
567 | ||||
568 | hin_mode |= (ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); | |||
569 | } | |||
570 | ||||
571 | if (!SetConsoleMode (d->hin, hin_mode) || | |||
572 | !SetConsoleMode (d->hout, hout_mode)) | |||
573 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
574 | } | |||
575 | ||||
576 | #endif | |||
577 | ||||
578 | return e; | |||
579 | } | |||
580 | ||||
581 | ||||
582 | ___HIDDENstatic ___SCMOBJlong ___device_tty_mode_restore | |||
583 | ___P((___device_tty *self,(___device_tty *self, int remove) | |||
584 | ___BOOL remove),(___device_tty *self, int remove) | |||
585 | (self,(___device_tty *self, int remove) | |||
586 | remove)(___device_tty *self, int remove) | |||
587 | ___device_tty *self;(___device_tty *self, int remove) | |||
588 | ___BOOL remove;)(___device_tty *self, int remove) | |||
589 | { | |||
590 | ___device_tty *d = self; | |||
591 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
592 | ___device_tty *curr = ___tty_mod.mode_save_stack; | |||
593 | ___device_tty *prev = NULL((void*)0); | |||
594 | ___device_tty *next; | |||
595 | ||||
596 | while (curr != d) | |||
597 | { | |||
598 | if ((e = ___device_tty_mode_update (curr, 0)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
599 | break; | |||
600 | next = curr->mode_save_stack_next; | |||
601 | curr->mode_save_stack_next = prev; | |||
602 | prev = curr; | |||
603 | curr = next; | |||
604 | } | |||
605 | ||||
606 | if (e == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
607 | curr != NULL((void*)0) && | |||
608 | (e = ___device_tty_mode_update (curr, !remove)) == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
609 | remove) | |||
610 | { | |||
611 | d->stage = TTY_STAGE_MODE_NOT_SAVED1; | |||
612 | curr = curr->mode_save_stack_next; /* remove d from mode save stack */ | |||
613 | } | |||
614 | ||||
615 | while (prev != NULL((void*)0)) | |||
616 | { | |||
617 | ___SCMOBJlong e2; | |||
618 | next = curr; | |||
619 | curr = prev; | |||
620 | prev = prev->mode_save_stack_next; | |||
621 | curr->mode_save_stack_next = next; | |||
622 | if ((e2 = ___device_tty_mode_get (curr)) != ___FIX(___NO_ERR)(((long)(0))<<2) || | |||
623 | (e2 = ___device_tty_mode_update (curr, 1)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
624 | { | |||
625 | if (e == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
626 | e = e2; | |||
627 | } | |||
628 | } | |||
629 | ||||
630 | ___tty_mod.mode_save_stack = curr; | |||
631 | ||||
632 | return e; | |||
633 | } | |||
634 | ||||
635 | ||||
636 | ___HIDDENstatic ___SCMOBJlong ___device_tty_mode_set | |||
637 | ___P((___device_tty *self,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
638 | ___BOOL input_allow_special,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
639 | ___BOOL input_echo,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
640 | ___BOOL input_raw,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
641 | ___BOOL output_raw,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
642 | int speed),(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
643 | (self,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
644 | input_allow_special,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
645 | input_echo,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
646 | input_raw,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
647 | output_raw,(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
648 | speed)(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
649 | ___device_tty *self;(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
650 | ___BOOL input_allow_special;(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
651 | ___BOOL input_echo;(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
652 | ___BOOL input_raw;(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
653 | ___BOOL output_raw;(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
654 | int speed;)(___device_tty *self, int input_allow_special, int input_echo , int input_raw, int output_raw, int speed) | |||
655 | { | |||
656 | ___device_tty *d = self; | |||
657 | ||||
658 | /**************** TODO: begin critical section (must block SIGCONT) */ | |||
659 | d->input_allow_special = input_allow_special; | |||
660 | d->input_echo = input_echo; | |||
661 | d->input_raw = input_raw; | |||
662 | d->output_raw = output_raw; | |||
663 | d->speed = speed; | |||
664 | /**************** TODO: end critical section (must block SIGCONT) */ | |||
665 | ||||
666 | return ___device_tty_mode_restore (d, 0); | |||
667 | } | |||
668 | ||||
669 | ||||
670 | ___HIDDENstatic ___SCMOBJlong ___device_tty_update_size | |||
671 | ___P((___device_tty *self),(___device_tty *self) | |||
672 | (self)(___device_tty *self) | |||
673 | ___device_tty *self;)(___device_tty *self) | |||
674 | { | |||
675 | ___device_tty *d = self; | |||
676 | ||||
677 | if (d->size_needs_update) | |||
678 | { | |||
679 | int prev_line_start_col = d->current.line_start % d->terminal_nb_cols; | |||
680 | int prev_line_start_row = d->current.line_start / d->terminal_nb_cols; | |||
681 | ||||
682 | #ifdef USE_POSIX | |||
683 | ||||
684 | #ifdef USE_ioctl | |||
685 | #ifdef TIOCGWINSZ0x5413 | |||
686 | ||||
687 | struct winsize size; | |||
688 | ||||
689 | if (ioctl (d->fd, TIOCGWINSZ0x5413, &size) < 0) | |||
690 | return err_code_from_errno ()___err_code_from_errno(); | |||
691 | ||||
692 | if (size.ws_col > 0) | |||
693 | d->terminal_nb_cols = size.ws_col; | |||
694 | ||||
695 | if (size.ws_row > 0) | |||
696 | d->terminal_nb_rows = size.ws_row; | |||
697 | ||||
698 | #endif | |||
699 | #endif | |||
700 | ||||
701 | #endif | |||
702 | ||||
703 | #ifdef USE_WIN32 | |||
704 | ||||
705 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
706 | ||||
707 | if (!GetConsoleScreenBufferInfo (self->hout, &info)) | |||
708 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
709 | ||||
710 | d->terminal_nb_cols = info.dwSize.X; | |||
711 | d->terminal_nb_rows = info.dwSize.Y; | |||
712 | ||||
713 | #endif | |||
714 | ||||
715 | d->terminal_size = | |||
716 | d->terminal_nb_rows * d->terminal_nb_cols; | |||
717 | ||||
718 | d->terminal_cursor = | |||
719 | d->terminal_row * d->terminal_nb_cols + d->terminal_col; | |||
720 | ||||
721 | d->current.line_start = | |||
722 | prev_line_start_row * d->terminal_nb_cols + prev_line_start_col; | |||
723 | ||||
724 | d->terminal_delayed_wrap = 0; | |||
725 | ||||
726 | d->size_needs_update = 0; | |||
727 | } | |||
728 | ||||
729 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
730 | } | |||
731 | ||||
732 | ||||
733 | ___HIDDENstatic ___BOOLint lineeditor_under_emacs ___PVOID(void) | |||
734 | { | |||
735 | static ___UCS_2unsigned short emacs_env_name[] = { 'E', 'M', 'A', 'C', 'S', '\0' }; | |||
736 | ___UCS_2STRINGunsigned short* cvalue; | |||
737 | ||||
738 | if (___getenv_UCS_2 (emacs_env_name, &cvalue) == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
739 | { | |||
740 | if (cvalue != 0) | |||
741 | { | |||
742 | ___free_mem (cvalue); | |||
743 | return 1; | |||
744 | } | |||
745 | } | |||
746 | ||||
747 | return 0; | |||
748 | } | |||
749 | ||||
750 | ||||
751 | #ifdef USE_WIN32 | |||
752 | ||||
753 | #if 0 | |||
754 | #ifdef USE_GetConsoleWindow | |||
755 | ||||
756 | ___BEGIN_C_LINKAGE | |||
757 | HWND WINAPI GetConsoleWindow (void); | |||
758 | ___END_C_LINKAGE | |||
759 | ||||
760 | #endif | |||
761 | #endif | |||
762 | ||||
763 | ___HIDDENstatic BOOL WINAPI console_event_handler | |||
764 | ___P((DWORD dwCtrlType),(DWORD dwCtrlType) | |||
765 | ())(DWORD dwCtrlType); | |||
766 | ||||
767 | #endif | |||
768 | ||||
769 | ||||
770 | /* forward declaration */ | |||
771 | ||||
772 | ___HIDDENstatic ___SCMOBJlong lineeditor_redraw | |||
773 | ___P((___device_tty *self),(___device_tty *self) | |||
774 | ())(___device_tty *self); | |||
775 | ||||
776 | ||||
777 | ___HIDDENstatic ___SCMOBJlong ___device_tty_force_open | |||
778 | ___P((___device_tty *self),(___device_tty *self) | |||
779 | (self)(___device_tty *self) | |||
780 | ___device_tty *self;)(___device_tty *self) | |||
781 | { | |||
782 | ___device_tty *d = self; | |||
783 | ||||
784 | switch (d->stage) | |||
785 | { | |||
786 | case TTY_STAGE_NOT_OPENED0: | |||
787 | { | |||
788 | #ifdef USE_POSIX | |||
789 | ||||
790 | int fd; | |||
791 | ||||
792 | #ifndef HAVE_ctermid | |||
793 | char* term_name = "/dev/tty"; | |||
794 | #else | |||
795 | char term_name[L_ctermid9]; | |||
796 | ctermid (term_name); /* get controlling terminal's name */ | |||
797 | #endif | |||
798 | ||||
799 | if ((fd = open (term_name, | |||
800 | #ifdef LINEEDITOR_WITH_NONBLOCKING_IO | |||
801 | O_NONBLOCK04000 | | |||
802 | #endif | |||
803 | #ifdef O_BINARY | |||
804 | O_BINARY | | |||
805 | #endif | |||
806 | O_RDWR02, | |||
807 | 0)) | |||
808 | < 0) | |||
809 | { | |||
810 | #ifdef ENXIO6 | |||
811 | if (errno(*__errno_location ()) == ENXIO6) | |||
812 | { | |||
813 | /* | |||
814 | * There is no controlling terminal! This is a fatal | |||
815 | * error, because trying to display an error message | |||
816 | * will just cause the open to be tried again to | |||
817 | * report the problem, and this will lead to an | |||
818 | * infinite loop. | |||
819 | */ | |||
820 | ||||
821 | static char *msgs[] = | |||
822 | { "No controlling terminal (try using the -:d- runtime option)", | |||
823 | NULL((void*)0) | |||
824 | }; | |||
825 | ||||
826 | ___fatal_error (msgs); | |||
827 | } | |||
828 | #endif | |||
829 | return fnf_or_err_code_from_errno ()___err_code_from_errno(); | |||
830 | } | |||
831 | ||||
832 | d->fd = fd; | |||
833 | ||||
834 | #endif | |||
835 | ||||
836 | #ifdef USE_WIN32 | |||
837 | ||||
838 | DWORD m; | |||
839 | HANDLE in; | |||
840 | HANDLE out; | |||
841 | HANDLE sin = GetStdHandle (STD_INPUT_HANDLE); /* ignore error */ | |||
842 | HANDLE sout = GetStdHandle (STD_OUTPUT_HANDLE); /* ignore error */ | |||
843 | HANDLE serr = GetStdHandle (STD_ERROR_HANDLE); /* ignore error */ | |||
844 | ||||
845 | #ifdef USE_GetConsoleWindow | |||
846 | ||||
847 | HWND cons_wind = GetConsoleWindow (); | |||
848 | if (cons_wind == NULL((void*)0) || !IsWindowVisible (cons_wind)) | |||
849 | FreeConsole (); | |||
850 | ||||
851 | #endif | |||
852 | ||||
853 | if (AllocConsole ()) | |||
854 | { | |||
855 | /* restore initial standard handles */ | |||
856 | ||||
857 | SetConsoleCtrlHandler (console_event_handler, TRUE); /* ignore error */ | |||
858 | SetStdHandle (STD_INPUT_HANDLE, sin); /* ignore error */ | |||
859 | SetStdHandle (STD_OUTPUT_HANDLE, sout); /* ignore error */ | |||
860 | SetStdHandle (STD_ERROR_HANDLE, serr); /* ignore error */ | |||
861 | } | |||
862 | ||||
863 | in = CreateFile | |||
864 | (_T("CONIN$"), | |||
865 | GENERIC_READ | GENERIC_WRITE, | |||
866 | FILE_SHARE_READ | FILE_SHARE_WRITE, | |||
867 | NULL((void*)0), | |||
868 | OPEN_EXISTING, | |||
869 | 0, | |||
870 | NULL((void*)0)); | |||
871 | ||||
872 | if (in == INVALID_HANDLE_VALUE) | |||
873 | return fnf_or_err_code_from_GetLastError ()___fnf_or_err_code_from_GetLastError(); | |||
874 | ||||
875 | out = CreateFile | |||
876 | (_T("CONOUT$"), | |||
877 | GENERIC_READ | GENERIC_WRITE, | |||
878 | FILE_SHARE_READ | FILE_SHARE_WRITE, | |||
879 | NULL((void*)0), | |||
880 | OPEN_EXISTING, | |||
881 | 0, | |||
882 | NULL((void*)0)); | |||
883 | ||||
884 | if (out == INVALID_HANDLE_VALUE) | |||
885 | { | |||
886 | ___SCMOBJlong e = fnf_or_err_code_from_GetLastError ()___fnf_or_err_code_from_GetLastError(); | |||
887 | CloseHandle (in); /* ignore error */ | |||
888 | return e; | |||
889 | } | |||
890 | ||||
891 | d->hin = in; | |||
892 | d->hout = out; | |||
893 | ||||
894 | #endif | |||
895 | ||||
896 | d->stage = TTY_STAGE_MODE_NOT_SAVED1; | |||
897 | ||||
898 | /* fall through */ | |||
899 | } | |||
900 | ||||
901 | case TTY_STAGE_MODE_NOT_SAVED1: | |||
902 | { | |||
903 | ___SCMOBJlong e; | |||
904 | ||||
905 | if ((e = ___device_tty_mode_save (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
906 | return e; | |||
907 | ||||
908 | /* fall through */ | |||
909 | } | |||
910 | ||||
911 | case TTY_STAGE_MODE_NOT_SET2: | |||
912 | { | |||
913 | ___SCMOBJlong e; | |||
914 | ||||
915 | if ((e = ___device_tty_mode_restore (d, 0)) | |||
916 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
917 | return e; | |||
918 | ||||
919 | d->stage = TTY_STAGE_INIT_DONE3; | |||
920 | } | |||
921 | } | |||
922 | ||||
923 | if (d->size_needs_update) | |||
924 | { | |||
925 | ___SCMOBJlong e; | |||
926 | int prev_nb_cols = d->terminal_nb_cols; | |||
927 | ||||
928 | if ((e = ___device_tty_update_size (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
929 | return e; | |||
930 | ||||
931 | if (d->editing_line && prev_nb_cols != d->terminal_nb_cols) | |||
932 | if ((e = lineeditor_redraw (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
933 | return e; | |||
934 | } | |||
935 | ||||
936 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
937 | } | |||
938 | ||||
939 | ||||
940 | #ifdef USE_WIN32 | |||
941 | ||||
942 | ___HIDDENstatic void show_cursor | |||
943 | ___P((___device_tty *self),(___device_tty *self) | |||
944 | (self)(___device_tty *self) | |||
945 | ___device_tty *self;)(___device_tty *self) | |||
946 | { | |||
947 | ___device_tty *d = self; | |||
948 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
949 | ||||
950 | if (GetConsoleScreenBufferInfo (d->hout, &info)) | |||
951 | SetConsoleCursorPosition | |||
952 | (d->hout, | |||
953 | info.dwCursorPosition); /* ignore error */ | |||
954 | } | |||
955 | ||||
956 | #endif | |||
957 | ||||
958 | ||||
959 | ___HIDDENstatic ___SCMOBJlong ___device_tty_write | |||
960 | ___P((___device_tty *self,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
961 | ___U8 *buf,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
962 | ___stream_index len,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
963 | ___stream_index *len_done),(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
964 | (self,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
965 | buf,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
966 | len,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
967 | len_done)(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
968 | ___device_tty *self;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
969 | ___U8 *buf;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
970 | ___stream_index len;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
971 | ___stream_index *len_done;)(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
972 | { | |||
973 | ___device_tty *d = self; | |||
974 | ||||
975 | #ifdef USE_POSIX | |||
976 | ||||
977 | { | |||
978 | int n; | |||
979 | ||||
980 | if ((n = write (d->fd, buf, len)) < 0) | |||
981 | return err_code_from_errno ()___err_code_from_errno(); | |||
982 | ||||
983 | *len_done = n; | |||
984 | } | |||
985 | ||||
986 | #endif | |||
987 | ||||
988 | #ifdef USE_WIN32 | |||
989 | ||||
990 | { | |||
991 | DWORD n; | |||
992 | int len_in_chars = TTY_CHAR_SELECT(len,len>>1)len; /* convert bytes to chars */ | |||
993 | ||||
994 | if (len_in_chars < 1) | |||
995 | return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
996 | ||||
997 | if (!TTY_CHAR_SELECT(WriteConsoleA (d->hout, buf, len_in_chars, &n, NULL),WriteConsoleA (d->hout, buf, len_in_chars, &n, ((void* )0)) | |||
998 | WriteConsoleW (d->hout, buf, len_in_chars, &n, NULL))WriteConsoleA (d->hout, buf, len_in_chars, &n, ((void* )0))) | |||
999 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
1000 | ||||
1001 | show_cursor (d); | |||
1002 | ||||
1003 | *len_done = TTY_CHAR_SELECT(n,n<<1)n; /* convert chars to bytes */ | |||
1004 | } | |||
1005 | ||||
1006 | #endif | |||
1007 | ||||
1008 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1009 | } | |||
1010 | ||||
1011 | ||||
1012 | ___HIDDENstatic ___SCMOBJlong ___device_tty_write_raw_no_lineeditor | |||
1013 | ___P((___device_tty *self,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1014 | ___U8 *buf,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1015 | ___stream_index len,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1016 | ___stream_index *len_done),(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1017 | (self,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1018 | buf,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1019 | len,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1020 | len_done)(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1021 | ___device_tty *self;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1022 | ___U8 *buf;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1023 | ___stream_index len;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1024 | ___stream_index *len_done;)(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1025 | { | |||
1026 | ___device_tty *d = self; | |||
1027 | ||||
1028 | if (d->base.base.write_stage != ___STAGE_OPEN0) | |||
1029 | return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+6)))<<2); | |||
1030 | ||||
1031 | return ___device_tty_write (d, buf, len, len_done); | |||
1032 | } | |||
1033 | ||||
1034 | ___HIDDENstatic ___SCMOBJlong ___device_tty_read_raw_no_lineeditor | |||
1035 | ___P((___device_tty *self,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1036 | ___U8 *buf,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1037 | ___stream_index len,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1038 | ___stream_index *len_done),(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1039 | (self,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1040 | buf,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1041 | len,(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1042 | len_done)(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1043 | ___device_tty *self;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1044 | ___U8 *buf;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1045 | ___stream_index len;(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1046 | ___stream_index *len_done;)(___device_tty *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
1047 | { | |||
1048 | ___device_tty *d = self; | |||
1049 | ||||
1050 | if (d->base.base.read_stage != ___STAGE_OPEN0) | |||
1051 | return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+6)))<<2); | |||
1052 | ||||
1053 | #ifdef USE_POSIX | |||
1054 | ||||
1055 | { | |||
1056 | int n; | |||
1057 | ||||
1058 | #ifdef ___DEBUG | |||
1059 | ___printf ("read len=%d\n", len); | |||
1060 | #endif | |||
1061 | ||||
1062 | if ((n = read (d->fd, buf, len)) < 0) | |||
1063 | return err_code_from_errno ()___err_code_from_errno(); | |||
1064 | ||||
1065 | #ifdef ___DEBUG | |||
1066 | ___printf ("read n=%d\n", n); | |||
1067 | #endif | |||
1068 | ||||
1069 | *len_done = n; | |||
1070 | } | |||
1071 | ||||
1072 | #endif | |||
1073 | ||||
1074 | #ifdef USE_WIN32 | |||
1075 | ||||
1076 | { | |||
1077 | char *seq; | |||
1078 | int len_in_chars = TTY_CHAR_SELECT(len,len>>1)len; /* convert bytes to chars */ | |||
1079 | ||||
1080 | if (len_in_chars < 1) | |||
1081 | return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
1082 | ||||
1083 | next_chars: | |||
1084 | ||||
1085 | seq = d->key_seq; | |||
1086 | ||||
1087 | if (seq != NULL((void*)0)) | |||
1088 | { | |||
1089 | TTY_CHARunsigned char *tty_char_buf = ___CAST(TTY_CHAR*,buf)((unsigned char*)(buf)); | |||
1090 | int i = 0; | |||
1091 | ||||
1092 | while (i < len_in_chars && *seq != '\0') | |||
1093 | { | |||
1094 | *tty_char_buf++ = *seq++; | |||
1095 | i++; | |||
1096 | } | |||
1097 | ||||
1098 | if (*seq == '\0') | |||
1099 | d->key_seq = NULL((void*)0); | |||
1100 | else | |||
1101 | d->key_seq = seq; | |||
1102 | ||||
1103 | if (i > 0) | |||
1104 | { | |||
1105 | *len_done = TTY_CHAR_SELECT(i,i<<1)i; /* convert chars to bytes */ | |||
1106 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1107 | } | |||
1108 | } | |||
1109 | ||||
1110 | next_event: | |||
1111 | ||||
1112 | if (d->ir.EventType != KEY_EVENT || | |||
1113 | d->ir.Event.KeyEvent.wRepeatCount <= 0) | |||
1114 | { | |||
1115 | DWORD avail; | |||
1116 | ||||
1117 | if (!GetNumberOfConsoleInputEvents (d->hin, &avail)) | |||
1118 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
1119 | ||||
1120 | if (avail <= 0) | |||
1121 | return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<< 16)+(11)))))<<2); | |||
1122 | ||||
1123 | if (!TTY_CHAR_SELECT(ReadConsoleInputA (d->hin, &d->ir, 1, &avail),ReadConsoleInputA (d->hin, &d->ir, 1, &avail) | |||
1124 | ReadConsoleInputW (d->hin, &d->ir, 1, &avail))ReadConsoleInputA (d->hin, &d->ir, 1, &avail)) | |||
1125 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
1126 | ||||
1127 | if (avail <= 0) | |||
1128 | return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<< 16)+(11)))))<<2); | |||
1129 | } | |||
1130 | ||||
1131 | switch (d->ir.EventType) | |||
1132 | { | |||
1133 | case KEY_EVENT: | |||
1134 | { | |||
1135 | DWORD ctrl_keys; | |||
1136 | ___BOOLint ctrl; | |||
1137 | ___BOOLint alt; | |||
1138 | ___BOOLint shift; | |||
1139 | char *seq; | |||
1140 | TTY_CHARunsigned char c; | |||
1141 | ||||
1142 | if (!(d->ir.Event.KeyEvent.bKeyDown && | |||
1143 | d->ir.Event.KeyEvent.wRepeatCount > 0)) | |||
1144 | { | |||
1145 | d->ir.EventType = MOUSE_EVENT; /* anything but KEY_EVENT */ | |||
1146 | goto next_event; | |||
1147 | } | |||
1148 | ||||
1149 | ctrl_keys = d->ir.Event.KeyEvent.dwControlKeyState; | |||
1150 | ctrl = ctrl_keys & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED); | |||
1151 | alt = ctrl_keys & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED); | |||
1152 | shift = ctrl_keys & SHIFT_PRESSED; | |||
1153 | ||||
1154 | c = TTY_CHAR_SELECT(d->ir.Event.KeyEvent.uChar.AsciiChar,d->ir.Event.KeyEvent.uChar.AsciiChar | |||
1155 | d->ir.Event.KeyEvent.uChar.UnicodeChar)d->ir.Event.KeyEvent.uChar.AsciiChar; | |||
1156 | ||||
1157 | seq = NULL((void*)0); | |||
1158 | ||||
1159 | if (!ctrl && alt && !shift && c>='a' && c<='z') | |||
1160 | { | |||
1161 | static char alt_seq[3]; | |||
1162 | alt_seq[0] = ___UNICODE_ESCAPE27; | |||
1163 | alt_seq[1] = c; | |||
1164 | alt_seq[2] = '\0'; | |||
1165 | seq = alt_seq; | |||
1166 | } | |||
1167 | else if (!ctrl && !alt && !shift && c == 0) | |||
1168 | switch (d->ir.Event.KeyEvent.wVirtualKeyCode) | |||
1169 | { | |||
1170 | case VK_BACK: seq = "\010"; break; | |||
1171 | case VK_UP: seq = "\033[A"; break; | |||
1172 | case VK_DOWN: seq = "\033[B"; break; | |||
1173 | case VK_RIGHT: seq = "\033[C"; break; | |||
1174 | case VK_LEFT: seq = "\033[D"; break; | |||
1175 | case VK_HOME: seq = "\033[H"; break; | |||
1176 | case VK_INSERT: seq = "\033[2~"; break; | |||
1177 | case VK_DELETE: seq = "\177"; break; | |||
1178 | case VK_END: seq = "\033[F"; break; | |||
1179 | case VK_PRIOR: seq = "\033[5~"; break; | |||
1180 | case VK_NEXT: seq = "\033[6~"; break; | |||
1181 | case VK_F1: seq = "\033OP"; break; | |||
1182 | case VK_F2: seq = "\033OQ"; break; | |||
1183 | case VK_F3: seq = "\033OR"; break; | |||
1184 | case VK_F4: seq = "\033OS"; break; | |||
1185 | case VK_F5: seq = "\033[15~"; break; | |||
1186 | case VK_F6: seq = "\033[17~"; break; | |||
1187 | case VK_F7: seq = "\033[18~"; break; | |||
1188 | case VK_F8: seq = "\033[19~"; break; | |||
1189 | case VK_F9: seq = "\033[20~"; break; | |||
1190 | case VK_F10: seq = "\033[21~"; break; | |||
1191 | case VK_F11: seq = "\033[23~"; break; | |||
1192 | case VK_F12: seq = "\033[24~"; break; | |||
1193 | } | |||
1194 | ||||
1195 | if (seq == NULL((void*)0)) | |||
1196 | { | |||
1197 | if (c == 0) | |||
1198 | { | |||
1199 | d->ir.EventType = MOUSE_EVENT; /* anything but KEY_EVENT */ | |||
1200 | goto next_event; | |||
1201 | } | |||
1202 | ||||
1203 | if (ctrl && c == ' ') /* ctrl-space => NUL character */ | |||
1204 | c = '\0'; | |||
1205 | ||||
1206 | TTY_CHAR_SELECT(buf[0] = c & 0xff; *len_done = 1; | |||
1207 | buf[0] = c & 0xff;buf[0] = c & 0xff; *len_done = 1; | |||
1208 | *len_done = 1;buf[0] = c & 0xff; *len_done = 1; | |||
1209 | ,buf[0] = c & 0xff; *len_done = 1; | |||
1210 | buf[0] = c & 0xff;buf[0] = c & 0xff; *len_done = 1; | |||
1211 | buf[1] = c >> 8;buf[0] = c & 0xff; *len_done = 1; | |||
1212 | *len_done = 2;buf[0] = c & 0xff; *len_done = 1; | |||
1213 | )buf[0] = c & 0xff; *len_done = 1; | |||
1214 | ||||
1215 | d->ir.Event.KeyEvent.wRepeatCount--; | |||
1216 | ||||
1217 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1218 | } | |||
1219 | else | |||
1220 | { | |||
1221 | d->key_seq = seq; | |||
1222 | d->ir.Event.KeyEvent.wRepeatCount--; | |||
1223 | goto next_chars; | |||
1224 | } | |||
1225 | ||||
1226 | break; | |||
1227 | } | |||
1228 | ||||
1229 | case MOUSE_EVENT: | |||
1230 | { | |||
1231 | #if 0 | |||
1232 | /*************************/ | |||
1233 | COORD c = d->ir.Event.MouseEvent.dwMousePosition; | |||
1234 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
1235 | COORD pos; | |||
1236 | ||||
1237 | printf ("m.X=%d m.Y=%d\n",c.X,c.Y); | |||
1238 | if (GetConsoleScreenBufferInfo (d->hout, &info)) | |||
1239 | { | |||
1240 | printf (" dwSize.X=%d dwSize.Y=%d\n",info.dwSize.X,info.dwSize.Y); | |||
1241 | printf (" dwCursorPosition.X=%d dwCursorPosition.Y=%d\n",info.dwCursorPosition.X,info.dwCursorPosition.Y); | |||
1242 | printf (" dwMaximumWindowSize.X=%d dwMaximumWindowSize.Y=%d\n",info.dwMaximumWindowSize.X,info.dwMaximumWindowSize.Y); | |||
1243 | printf (" srWindow.Left=%d srWindow.Top=%d\n",info.srWindow.Left,info.srWindow.Top); | |||
1244 | printf (" srWindow.Right=%d srWindow.Bottom=%d\n",info.srWindow.Right,info.srWindow.Bottom); | |||
1245 | fflush(stdoutstdout); | |||
1246 | } | |||
1247 | ||||
1248 | ___WORDlong e; | |||
1249 | ||||
1250 | if (i > 0) | |||
1251 | goto done; /* in case paste returns an error */ | |||
1252 | ||||
1253 | state->input_rlo++; | |||
1254 | ||||
1255 | if (d->ir.Event.MouseEvent.dwEventFlags == 0 && | |||
1256 | (d->ir.Event.MouseEvent.dwButtonState == | |||
1257 | (FROM_LEFT_1ST_BUTTON_PRESSED | RIGHTMOST_BUTTON_PRESSED) || | |||
1258 | d->ir.Event.MouseEvent.dwButtonState == | |||
1259 | FROM_LEFT_2ND_BUTTON_PRESSED)) | |||
1260 | if ((e = lineeditor_paste_from_clipboard (state->les)) | |||
1261 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1262 | return e; | |||
1263 | ||||
1264 | goto done; /* pasted text is available to be read */ | |||
1265 | #endif | |||
1266 | goto next_event; | |||
1267 | } | |||
1268 | ||||
1269 | case WINDOW_BUFFER_SIZE_EVENT: | |||
1270 | { | |||
1271 | d->size_needs_update = 1; | |||
1272 | #if 0 | |||
1273 | COORD c = d->ir.Event.WindowBufferSizeEvent.dwSize; | |||
1274 | printf ("c.X=%d c.Y=%d\n", c.X, c.Y);fflush(stdoutstdout);/********************/ | |||
1275 | #endif | |||
1276 | goto next_event; | |||
1277 | } | |||
1278 | ||||
1279 | default: | |||
1280 | goto next_event; | |||
1281 | } | |||
1282 | } | |||
1283 | ||||
1284 | #endif | |||
1285 | ||||
1286 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1287 | } | |||
1288 | ||||
1289 | ||||
1290 | /*****************************************************************************/ | |||
1291 | ||||
1292 | /* Line editing subsystem */ | |||
1293 | ||||
1294 | ||||
1295 | #ifdef USE_LINEEDITOR | |||
1296 | ||||
1297 | ||||
1298 | /*---------------------------------------------------------------------------*/ | |||
1299 | ||||
1300 | /* Line editing input decoder routines */ | |||
1301 | ||||
1302 | ||||
1303 | ___HIDDENstatic ___SCMOBJlong lineeditor_input_decoder_setup | |||
1304 | ___P((lineeditor_input_decoder *decoder),(lineeditor_input_decoder *decoder) | |||
1305 | (decoder)(lineeditor_input_decoder *decoder) | |||
1306 | lineeditor_input_decoder *decoder;)(lineeditor_input_decoder *decoder) | |||
1307 | { | |||
1308 | #define LINEEDITOR_INPUT_DECODER_INITIAL_BUFFER_SIZE150 150 | |||
1309 | ||||
1310 | int n = LINEEDITOR_INPUT_DECODER_INITIAL_BUFFER_SIZE150; | |||
1311 | ||||
1312 | decoder->buffer = ___CAST(lineeditor_input_test*,((lineeditor_input_test*)(___alloc_mem (n * sizeof (lineeditor_input_test )))) | |||
1313 | ___alloc_mem (n * sizeof (lineeditor_input_test)))((lineeditor_input_test*)(___alloc_mem (n * sizeof (lineeditor_input_test )))); | |||
1314 | ||||
1315 | if (decoder->buffer == NULL((void*)0)) | |||
1316 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
1317 | ||||
1318 | decoder->length = 0; | |||
1319 | decoder->max_length = n; | |||
1320 | ||||
1321 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1322 | } | |||
1323 | ||||
1324 | ||||
1325 | ___HIDDENstatic void lineeditor_input_decoder_cleanup | |||
1326 | ___P((lineeditor_input_decoder *decoder),(lineeditor_input_decoder *decoder) | |||
1327 | (decoder)(lineeditor_input_decoder *decoder) | |||
1328 | lineeditor_input_decoder *decoder;)(lineeditor_input_decoder *decoder) | |||
1329 | { | |||
1330 | ___free_mem (decoder->buffer); | |||
1331 | } | |||
1332 | ||||
1333 | ||||
1334 | ___HIDDENstatic ___SCMOBJlong lineeditor_input_decoder_set_length | |||
1335 | ___P((lineeditor_input_decoder *decoder,(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1336 | int len,(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1337 | int fudge),(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1338 | (decoder,(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1339 | len,(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1340 | fudge)(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1341 | lineeditor_input_decoder *decoder;(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1342 | int len;(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1343 | int fudge;)(lineeditor_input_decoder *decoder, int len, int fudge) | |||
1344 | { | |||
1345 | if (len > LINEEDITOR_INPUT_DECODER_MAX_LENGTH(255 -55 -1)) | |||
1346 | return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
1347 | ||||
1348 | if (len > decoder->max_length) | |||
1349 | { | |||
1350 | int i; | |||
1351 | int new_max_length = (fudge<0) ? 3*len/2+1 : len+fudge; | |||
1352 | lineeditor_input_test *old_buffer = decoder->buffer; | |||
1353 | lineeditor_input_test *new_buffer = | |||
1354 | ___CAST(lineeditor_input_test*,((lineeditor_input_test*)(___alloc_mem (new_max_length * sizeof (lineeditor_input_test)))) | |||
1355 | ___alloc_mem (new_max_length *((lineeditor_input_test*)(___alloc_mem (new_max_length * sizeof (lineeditor_input_test)))) | |||
1356 | sizeof (lineeditor_input_test)))((lineeditor_input_test*)(___alloc_mem (new_max_length * sizeof (lineeditor_input_test)))); | |||
1357 | ||||
1358 | if (new_buffer == NULL((void*)0)) | |||
1359 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
1360 | ||||
1361 | i = decoder->length; | |||
1362 | if (i > len) | |||
1363 | i = len; | |||
1364 | ||||
1365 | while (i-- > 0) | |||
1366 | new_buffer[i] = old_buffer[i]; | |||
1367 | ||||
1368 | ___free_mem (old_buffer); | |||
1369 | decoder->buffer = new_buffer; | |||
1370 | decoder->max_length = new_max_length; | |||
1371 | } | |||
1372 | ||||
1373 | decoder->length = len; | |||
1374 | ||||
1375 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1376 | } | |||
1377 | ||||
1378 | ||||
1379 | ___HIDDENstatic ___SCMOBJlong lineeditor_input_decoder_add | |||
1380 | ___P((lineeditor_input_decoder *decoder,(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1381 | char *seq,(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1382 | ___U8 event),(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1383 | (decoder,(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1384 | seq,(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1385 | event)(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1386 | lineeditor_input_decoder *decoder;(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1387 | char *seq;(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1388 | ___U8 event;)(lineeditor_input_decoder *decoder, char *seq, unsigned char event ) | |||
1389 | { | |||
1390 | ___SCMOBJlong e; | |||
1391 | ___U8unsigned char b; | |||
1392 | int i = 0; | |||
1393 | char *p = seq; | |||
1394 | ||||
1395 | if (event & WITH_ESC_PREFIX(unsigned char)(1<<7)) | |||
1396 | b = ___UNICODE_ESCAPE27; | |||
1397 | else | |||
1398 | b = ___CAST_U8(*p++)(unsigned char)(*p++); | |||
1399 | ||||
1400 | if (decoder->length > 0) | |||
1401 | { | |||
1402 | while (b != ___CAST_U8('\0')(unsigned char)('\0') || p == seq+1) | |||
1403 | { | |||
1404 | if (decoder->buffer[i].trigger == b) | |||
1405 | { | |||
1406 | int a = decoder->buffer[i].action; | |||
1407 | if (a >= decoder->length) | |||
1408 | return ___FIX(___NO_ERR)(((long)(0))<<2); /* prefix of sequence exists */ | |||
1409 | i = a; | |||
1410 | b = ___CAST_U8(*p++)(unsigned char)(*p++); | |||
1411 | } | |||
1412 | else | |||
1413 | { | |||
1414 | int n = decoder->buffer[i].next; | |||
1415 | if (n >= decoder->length) | |||
1416 | { | |||
1417 | decoder->buffer[i].next = decoder->length; | |||
1418 | break; | |||
1419 | } | |||
1420 | i = n; | |||
1421 | } | |||
1422 | } | |||
1423 | } | |||
1424 | ||||
1425 | if (b != ___CAST_U8('\0')(unsigned char)('\0') || p == seq+1) | |||
1426 | { | |||
1427 | /* sequence is not a prefix of a preexisting sequence */ | |||
1428 | ||||
1429 | while (b != ___CAST_U8('\0')(unsigned char)('\0') || p == seq+1) | |||
1430 | { | |||
1431 | i = decoder->length; | |||
1432 | ||||
1433 | if ((e = lineeditor_input_decoder_set_length (decoder, i+1, -1)) | |||
1434 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1435 | return e; | |||
1436 | ||||
1437 | decoder->buffer[i].trigger = b; | |||
1438 | decoder->buffer[i].action = i+1; | |||
1439 | decoder->buffer[i].next = LINEEDITOR_INPUT_DECODER_STATE_MAX255; | |||
1440 | ||||
1441 | b = ___CAST_U8(*p++)(unsigned char)(*p++); | |||
1442 | } | |||
1443 | decoder->buffer[i].action = | |||
1444 | LINEEDITOR_INPUT_DECODER_STATE_MAX255-(event&~WITH_ESC_PREFIX(unsigned char)(1<<7)); | |||
1445 | } | |||
1446 | ||||
1447 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1448 | } | |||
1449 | ||||
1450 | ||||
1451 | typedef struct lineeditor_defseq_struct | |||
1452 | { | |||
1453 | char *seq; | |||
1454 | ___U8unsigned char event; | |||
1455 | } lineeditor_defseq; | |||
1456 | ||||
1457 | ||||
1458 | ___HIDDENstatic lineeditor_defseq lineeditor_defseq_common[] = | |||
1459 | { | |||
1460 | /* sequences that all terminals support */ | |||
1461 | ||||
1462 | { "\012", LINEEDITOR_EV_RETURN2 } | |||
1463 | ,{ "\015", LINEEDITOR_EV_RETURN2 } | |||
1464 | ,{ "\010", LINEEDITOR_EV_BACK3 } | |||
1465 | ,{ "\010", LINEEDITOR_EV_BACK_SEXPR5 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1466 | ,{ "\011", LINEEDITOR_EV_TAB6 } | |||
1467 | }; | |||
1468 | ||||
1469 | ||||
1470 | ___HIDDENstatic lineeditor_defseq lineeditor_defseq_map_rubout_to_backspace[] = | |||
1471 | { | |||
1472 | /* sequences that map the rubout key to backspace */ | |||
1473 | ||||
1474 | { "\177", LINEEDITOR_EV_BACK3 } | |||
1475 | ,{ "\177", LINEEDITOR_EV_BACK_WORD4 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1476 | }; | |||
1477 | ||||
1478 | ||||
1479 | ___HIDDENstatic lineeditor_defseq lineeditor_defseq_emacs[] = | |||
1480 | { | |||
1481 | /* sequences specific to emacs mode */ | |||
1482 | ||||
1483 | { "\0", LINEEDITOR_EV_MARK7 } | |||
1484 | ,{ "\031", LINEEDITOR_EV_PASTE8 } | |||
1485 | ,{ "\027", LINEEDITOR_EV_CUT9 } | |||
1486 | ,{ "\013", LINEEDITOR_EV_CUT_RIGHT10 } | |||
1487 | ,{ "\025", LINEEDITOR_EV_CUT_LEFT11 } | |||
1488 | ,{ "\014", LINEEDITOR_EV_REFRESH12 } | |||
1489 | ,{ "\024", LINEEDITOR_EV_TRANSPOSE13 } | |||
1490 | ,{ "\024", LINEEDITOR_EV_TRANSPOSE_SEXPR15 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1491 | ,{ "t", LINEEDITOR_EV_TRANSPOSE_WORD14 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1492 | ,{ "T", LINEEDITOR_EV_TRANSPOSE_WORD14 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1493 | ,{ "p", LINEEDITOR_EV_UP16 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1494 | ,{ "P", LINEEDITOR_EV_UP16 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1495 | ,{ "n", LINEEDITOR_EV_DOWN17 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1496 | ,{ "N", LINEEDITOR_EV_DOWN17 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1497 | ||||
1498 | ,{ "\020", LINEEDITOR_EV_UP16 } | |||
1499 | ,{ "\016", LINEEDITOR_EV_DOWN17 } | |||
1500 | ,{ "\006", LINEEDITOR_EV_RIGHT18 } | |||
1501 | ,{ "\002", LINEEDITOR_EV_LEFT21 } | |||
1502 | ,{ "\006", LINEEDITOR_EV_RIGHT_SEXPR20 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1503 | ,{ "f", LINEEDITOR_EV_RIGHT_WORD19 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1504 | ,{ "F", LINEEDITOR_EV_RIGHT_WORD19 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1505 | ,{ "\002", LINEEDITOR_EV_LEFT_SEXPR23 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1506 | ,{ "b", LINEEDITOR_EV_LEFT_WORD22 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1507 | ,{ "B", LINEEDITOR_EV_LEFT_WORD22 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1508 | ||||
1509 | ,{ "\001", LINEEDITOR_EV_HOME24 } | |||
1510 | ,{ "\004", LINEEDITOR_EV_DELETE27 } | |||
1511 | ,{ "\005", LINEEDITOR_EV_END30 } | |||
1512 | ,{ "\004", LINEEDITOR_EV_DELETE_SEXPR29 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1513 | ,{ "d", LINEEDITOR_EV_DELETE_WORD28 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1514 | ,{ "D", LINEEDITOR_EV_DELETE_WORD28 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1515 | }; | |||
1516 | ||||
1517 | ||||
1518 | ___HIDDENstatic lineeditor_defseq lineeditor_defseq_widespread[] = | |||
1519 | { | |||
1520 | /* sequences that many types of terminals support */ | |||
1521 | ||||
1522 | { "[A", LINEEDITOR_EV_UP16 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1523 | ,{ "[B", LINEEDITOR_EV_DOWN17 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1524 | ,{ "[C", LINEEDITOR_EV_RIGHT18 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1525 | ,{ "[D", LINEEDITOR_EV_LEFT21 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1526 | ||||
1527 | ,{ "\033[A", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1528 | ,{ "\033[B", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1529 | ,{ "\033[C", LINEEDITOR_EV_RIGHT_SEXPR20 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1530 | ,{ "\033[D", LINEEDITOR_EV_LEFT_SEXPR23 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1531 | ||||
1532 | ,{ "OA", LINEEDITOR_EV_UP16 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1533 | ,{ "OB", LINEEDITOR_EV_DOWN17 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1534 | ,{ "OC", LINEEDITOR_EV_RIGHT18 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1535 | ,{ "OD", LINEEDITOR_EV_LEFT21 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1536 | ||||
1537 | ,{ "\033OA", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1538 | ,{ "\033OB", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1539 | ,{ "\033OC", LINEEDITOR_EV_RIGHT_SEXPR20 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1540 | ,{ "\033OD", LINEEDITOR_EV_LEFT_SEXPR23 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1541 | ||||
1542 | ,{ "A", LINEEDITOR_EV_UP16 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1543 | ,{ "B", LINEEDITOR_EV_DOWN17 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1544 | ,{ "C", LINEEDITOR_EV_RIGHT18 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1545 | ,{ "D", LINEEDITOR_EV_LEFT21 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1546 | ||||
1547 | ,{ "\033A", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1548 | ,{ "\033B", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1549 | ,{ "\033C", LINEEDITOR_EV_RIGHT_SEXPR20 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1550 | ,{ "\033D", LINEEDITOR_EV_LEFT_SEXPR23 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1551 | ||||
1552 | #ifdef USE_XTERM_CTRL_COMBINATIONS | |||
1553 | ,{ "[5A", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1554 | ,{ "[5B", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1555 | ,{ "[5C", LINEEDITOR_EV_RIGHT_SEXPR20 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1556 | ,{ "[5D", LINEEDITOR_EV_LEFT_SEXPR23 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1557 | #endif | |||
1558 | ||||
1559 | ,{ "[1~", LINEEDITOR_EV_HOME24 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1560 | ,{ "[2~", LINEEDITOR_EV_INSERT26 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1561 | ,{ "[3~", LINEEDITOR_EV_DELETE27 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1562 | ,{ "[4~", LINEEDITOR_EV_END30 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1563 | ,{ "[5~", LINEEDITOR_EV_HOME_DOC25 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1564 | ,{ "[6~", LINEEDITOR_EV_END_DOC31 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1565 | ||||
1566 | ,{ "\033[1~", LINEEDITOR_EV_HOME_DOC25 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1567 | ,{ "\033[2~", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1568 | ,{ "\033[3~", LINEEDITOR_EV_DELETE_SEXPR29 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1569 | ,{ "\033[4~", LINEEDITOR_EV_END_DOC31 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1570 | ,{ "\033[5~", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1571 | ,{ "\033[6~", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1572 | ||||
1573 | ,{ "[H", LINEEDITOR_EV_HOME24 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1574 | ,{ "[L", LINEEDITOR_EV_INSERT26 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1575 | ,{ "[F", LINEEDITOR_EV_END30 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1576 | ,{ "\177", LINEEDITOR_EV_DELETE27 } | |||
1577 | ,{ "\033[H", LINEEDITOR_EV_HOME_DOC25 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1578 | ,{ "\177", LINEEDITOR_EV_DELETE_SEXPR29 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1579 | ,{ "\033[F", LINEEDITOR_EV_END_DOC31 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1580 | ||||
1581 | #ifdef USE_XTERM_CTRL_COMBINATIONS | |||
1582 | ,{ "[1;5~", LINEEDITOR_EV_HOME_DOC25 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1583 | ,{ "[2;5~", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1584 | ,{ "[3;5~", LINEEDITOR_EV_DELETE_SEXPR29 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1585 | ,{ "[4;5~", LINEEDITOR_EV_END_DOC31 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1586 | ,{ "[5;5~", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1587 | ,{ "[6;5~", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1588 | ||||
1589 | ,{ "[5H", LINEEDITOR_EV_HOME_DOC25 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1590 | ,{ "[5L", LINEEDITOR_EV_NONE0 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1591 | ,{ "[5F", LINEEDITOR_EV_END_DOC31 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1592 | #endif | |||
1593 | ||||
1594 | ,{ "OP", LINEEDITOR_EV_F132 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1595 | ,{ "OQ", LINEEDITOR_EV_F234 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1596 | ,{ "OR", LINEEDITOR_EV_F336 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1597 | ,{ "OS", LINEEDITOR_EV_F438 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1598 | ||||
1599 | ,{ "\033OP", LINEEDITOR_EV_META_F133 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1600 | ,{ "\033OQ", LINEEDITOR_EV_META_F235 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1601 | ,{ "\033OR", LINEEDITOR_EV_META_F337 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1602 | ,{ "\033OS", LINEEDITOR_EV_META_F439 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1603 | ||||
1604 | #ifdef USE_XTERM_CTRL_COMBINATIONS | |||
1605 | ,{ "O5P", LINEEDITOR_EV_META_F133 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1606 | ,{ "O5Q", LINEEDITOR_EV_META_F235 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1607 | ,{ "O5R", LINEEDITOR_EV_META_F337 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1608 | ,{ "O5S", LINEEDITOR_EV_META_F439 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1609 | #endif | |||
1610 | ||||
1611 | ,{ "[11~", LINEEDITOR_EV_F132 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1612 | ,{ "[12~", LINEEDITOR_EV_F234 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1613 | ,{ "[13~", LINEEDITOR_EV_F336 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1614 | ,{ "[14~", LINEEDITOR_EV_F438 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1615 | ||||
1616 | ,{ "\033[11~", LINEEDITOR_EV_META_F133 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1617 | ,{ "\033[12~", LINEEDITOR_EV_META_F235 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1618 | ,{ "\033[13~", LINEEDITOR_EV_META_F337 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1619 | ,{ "\033[14~", LINEEDITOR_EV_META_F439 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1620 | ||||
1621 | #ifdef USE_XTERM_CTRL_COMBINATIONS | |||
1622 | ,{ "[11;5~", LINEEDITOR_EV_META_F133 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1623 | ,{ "[12;5~", LINEEDITOR_EV_META_F235 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1624 | ,{ "[13;5~", LINEEDITOR_EV_META_F337 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1625 | ,{ "[14;5~", LINEEDITOR_EV_META_F439 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1626 | #endif | |||
1627 | ||||
1628 | #ifdef LINEEDITOR_SUPPORT_F5_TO_F12 | |||
1629 | ||||
1630 | ,{ "[15~", LINEEDITOR_EV_F540 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1631 | ,{ "[17~", LINEEDITOR_EV_F642 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1632 | ,{ "[18~", LINEEDITOR_EV_F744 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1633 | ,{ "[19~", LINEEDITOR_EV_F846 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1634 | ,{ "[20~", LINEEDITOR_EV_F948 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1635 | ,{ "[21~", LINEEDITOR_EV_F1050 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1636 | ,{ "[23~", LINEEDITOR_EV_F1152 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1637 | ,{ "[24~", LINEEDITOR_EV_F1254 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1638 | ||||
1639 | ,{ "\033[15~", LINEEDITOR_EV_META_F541 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1640 | ,{ "\033[17~", LINEEDITOR_EV_META_F643 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1641 | ,{ "\033[18~", LINEEDITOR_EV_META_F745 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1642 | ,{ "\033[19~", LINEEDITOR_EV_META_F847 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1643 | ,{ "\033[20~", LINEEDITOR_EV_META_F949 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1644 | ,{ "\033[21~", LINEEDITOR_EV_META_F1051 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1645 | ,{ "\033[23~", LINEEDITOR_EV_META_F1153 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1646 | ,{ "\033[24~", LINEEDITOR_EV_META_F1255 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1647 | ||||
1648 | #ifdef USE_XTERM_CTRL_COMBINATIONS | |||
1649 | ,{ "[15;5~", LINEEDITOR_EV_META_F541 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1650 | ,{ "[17;5~", LINEEDITOR_EV_META_F643 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1651 | ,{ "[18;5~", LINEEDITOR_EV_META_F745 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1652 | ,{ "[19;5~", LINEEDITOR_EV_META_F847 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1653 | ,{ "[20;5~", LINEEDITOR_EV_META_F949 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1654 | ,{ "[21;5~", LINEEDITOR_EV_META_F1051 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1655 | ,{ "[23;5~", LINEEDITOR_EV_META_F1153 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1656 | ,{ "[24;5~", LINEEDITOR_EV_META_F1255 | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1657 | #endif | |||
1658 | ||||
1659 | #endif | |||
1660 | }; | |||
1661 | ||||
1662 | ||||
1663 | ___HIDDENstatic ___SCMOBJlong lineeditor_defseq_install_table | |||
1664 | ___P((lineeditor_input_decoder *decoder,(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1665 | lineeditor_defseq *table,(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1666 | int len),(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1667 | (decoder,(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1668 | table,(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1669 | len)(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1670 | lineeditor_input_decoder *decoder;(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1671 | lineeditor_defseq *table;(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1672 | int len;)(lineeditor_input_decoder *decoder, lineeditor_defseq *table, int len) | |||
1673 | { | |||
1674 | ___SCMOBJlong e; | |||
1675 | int i; | |||
1676 | ||||
1677 | for (i=0; i<len; i++) | |||
1678 | if ((e = lineeditor_input_decoder_add | |||
1679 | (decoder, | |||
1680 | table[i].seq, | |||
1681 | table[i].event)) | |||
1682 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1683 | return e; | |||
1684 | ||||
1685 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1686 | } | |||
1687 | ||||
1688 | ||||
1689 | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | |||
1690 | ||||
1691 | ||||
1692 | #ifdef USE_CURSES | |||
1693 | ||||
1694 | ||||
1695 | typedef struct lineeditor_dkey_struct | |||
1696 | { | |||
1697 | char *cap; | |||
1698 | ___U8unsigned char event_no_escape; | |||
1699 | ___U8unsigned char event_with_escape; | |||
1700 | } lineeditor_dkey; | |||
1701 | ||||
1702 | ||||
1703 | #ifdef USE_TERMCAP | |||
1704 | ||||
1705 | #define DKEY(tcap_name,tinfo_name,xterm_def,event_no_esc,event_with_esc){ xterm_def, event_no_esc, event_with_esc | (unsigned char)(1 <<7) } \ | |||
1706 | { tcap_name, event_no_esc, event_with_esc | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1707 | ||||
1708 | #else | |||
1709 | ||||
1710 | #ifdef USE_TERMINFO | |||
1711 | ||||
1712 | #define DKEY(tcap_name,tinfo_name,xterm_def,event_no_esc,event_with_esc){ xterm_def, event_no_esc, event_with_esc | (unsigned char)(1 <<7) } \ | |||
1713 | { tinfo_name, event_no_esc, event_with_esc | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1714 | ||||
1715 | #else | |||
1716 | ||||
1717 | #define DKEY(tcap_name,tinfo_name,xterm_def,event_no_esc,event_with_esc){ xterm_def, event_no_esc, event_with_esc | (unsigned char)(1 <<7) } \ | |||
1718 | { xterm_def, event_no_esc, event_with_esc | WITH_ESC_PREFIX(unsigned char)(1<<7) } | |||
1719 | ||||
1720 | #endif | |||
1721 | ||||
1722 | #endif | |||
1723 | ||||
1724 | ||||
1725 | typedef struct lineeditor_dcap_struct | |||
1726 | { | |||
1727 | char *cap; | |||
1728 | #ifdef USE_TERMCAP_OR_TERMINFO | |||
1729 | char *xterm_cap; | |||
1730 | #endif | |||
1731 | } lineeditor_dcap; | |||
1732 | ||||
1733 | ||||
1734 | #ifdef USE_TERMCAP | |||
1735 | ||||
1736 | #define DCAP(tcap_name,tinfo_name,xterm_def){ xterm_def } { tcap_name, xterm_def } | |||
1737 | ||||
1738 | #else | |||
1739 | ||||
1740 | #ifdef USE_TERMINFO | |||
1741 | ||||
1742 | #define DCAP(tcap_name,tinfo_name,xterm_def){ xterm_def } { tinfo_name, xterm_def } | |||
1743 | ||||
1744 | #else | |||
1745 | ||||
1746 | #define DCAP(tcap_name,tinfo_name,xterm_def){ xterm_def } { xterm_def } | |||
1747 | ||||
1748 | #endif | |||
1749 | ||||
1750 | #endif | |||
1751 | ||||
1752 | ||||
1753 | ___HIDDENstatic lineeditor_dcap lineeditor_dcap_table[LINEEDITOR_CAP_LAST21+1] = | |||
1754 | { | |||
1755 | /* order must match LINEEDITOR_CAP_XXX */ | |||
1756 | ||||
1757 | DCAP("ho","home", "\033[H" ){ "\033[H" } /* home cursor */ | |||
1758 | ,DCAP("cl","clear","\033[H\033[J" ){ "\033[H\033[J" } /* home cursor and clear screen */ | |||
1759 | ,DCAP("up","cuu1", "\033[A" ){ "\033[A" } /* move up one line */ | |||
1760 | ,DCAP("do","cud1", "\033[B" ){ "\033[B" } /* move down one line */ | |||
1761 | ,DCAP("UP","cuu", "\033[%p1%dA" ){ "\033[%p1%dA" } /* move up N lines */ | |||
1762 | ,DCAP("DO","cud", "\033[%p1%dB" ){ "\033[%p1%dB" } /* move down N lines */ | |||
1763 | ,DCAP("RI","cuf", "\033[%p1%dC" ){ "\033[%p1%dC" } /* move right N columns */ | |||
1764 | ,DCAP("LE","cub", "\033[%p1%dD" ){ "\033[%p1%dD" } /* move left N columns */ | |||
1765 | ,DCAP("cm","cup", "\033[%i%p1%d;%p2%dH"){ "\033[%i%p1%d;%p2%dH" } /* move cursor to (ROW,COL) */ | |||
1766 | ,DCAP("me","sgr0", "\033[m" ){ "\033[m" } /* turn off all attributes */ | |||
1767 | ,DCAP("md","bold", "\033[1m" ){ "\033[1m" } /* turn on bold attribute */ | |||
1768 | ,DCAP("us","smul", "\033[4m" ){ "\033[4m" } /* turn on underline attribute */ | |||
1769 | ,DCAP("mr","rev", "\033[7m" ){ "\033[7m" } /* turn on reverse attribute */ | |||
1770 | ,DCAP("AF","setaf","\033[3%p1%dm" ){ "\033[3%p1%dm" } /* ANSI set foreground color */ | |||
1771 | ,DCAP("AB","setab","\033[4%p1%dm" ){ "\033[4%p1%dm" } /* ANSI set background color */ | |||
1772 | ,DCAP("cd","ed", "\033[J" ){ "\033[J" } /* erase to end of screen */ | |||
1773 | ,DCAP("ce","el", "\033[K" ){ "\033[K" } /* erase to end of line */ | |||
1774 | ,DCAP("cb","el1", "\033[1K" ){ "\033[1K" } /* erase to beginning of line */ | |||
1775 | ,DCAP(" 0"," 0", "\033[%p1%dt" ){ "\033[%p1%dt" } /* window operation with no arg */ | |||
1776 | ,DCAP(" 1"," 1", "\033[%p1%d;%p2%dt" ){ "\033[%p1%d;%p2%dt" } /* window operation with 1 arg */ | |||
1777 | ,DCAP(" 2"," 2", "\033[%p1%d;%p2%d;%p3%dt"){ "\033[%p1%d;%p2%d;%p3%dt" } /* window operation with 2 args */ | |||
1778 | ,DCAP(" 3"," 3", "\033]%p1%d;" ){ "\033]%p1%d;" } /* window operation with text arg */ | |||
1779 | }; | |||
1780 | ||||
1781 | ||||
1782 | ___HIDDENstatic lineeditor_dkey lineeditor_dkey_table[] = | |||
1783 | { | |||
1784 | DKEY("ku","kcuu1","\033OA", LINEEDITOR_EV_UP, LINEEDITOR_EV_NONE ){ "\033OA", 16, 0 | (unsigned char)(1<<7) } | |||
1785 | ,DKEY("kd","kcud1","\033OB", LINEEDITOR_EV_DOWN, LINEEDITOR_EV_NONE ){ "\033OB", 17, 0 | (unsigned char)(1<<7) } | |||
1786 | ,DKEY("kr","kcuf1","\033OC", LINEEDITOR_EV_RIGHT, LINEEDITOR_EV_RIGHT_SEXPR ){ "\033OC", 18, 20 | (unsigned char)(1<<7) } | |||
1787 | ,DKEY("kl","kcub1","\033OD", LINEEDITOR_EV_LEFT, LINEEDITOR_EV_LEFT_SEXPR ){ "\033OD", 21, 23 | (unsigned char)(1<<7) } | |||
1788 | ,DKEY("kh","khome","\033[1~", LINEEDITOR_EV_HOME, LINEEDITOR_EV_HOME_DOC ){ "\033[1~", 24, 25 | (unsigned char)(1<<7) } | |||
1789 | ,DKEY("kI","kich1","\033[2~", LINEEDITOR_EV_INSERT, LINEEDITOR_EV_NONE ){ "\033[2~", 26, 0 | (unsigned char)(1<<7) } | |||
1790 | ,DKEY("kD","kdch1","\033[3~", LINEEDITOR_EV_DELETE, LINEEDITOR_EV_DELETE_SEXPR){ "\033[3~", 27, 29 | (unsigned char)(1<<7) } | |||
1791 | ,DKEY("@7","kend", "\033[4~", LINEEDITOR_EV_END, LINEEDITOR_EV_END_DOC ){ "\033[4~", 30, 31 | (unsigned char)(1<<7) } | |||
1792 | ,DKEY("kP","kpp", "\033[5~", LINEEDITOR_EV_HOME_DOC,LINEEDITOR_EV_NONE ){ "\033[5~", 25, 0 | (unsigned char)(1<<7) } | |||
1793 | ,DKEY("kN","knp", "\033[6~", LINEEDITOR_EV_END_DOC, LINEEDITOR_EV_NONE ){ "\033[6~", 31, 0 | (unsigned char)(1<<7) } | |||
1794 | ,DKEY("k1","kf1", "\033OP", LINEEDITOR_EV_F1, LINEEDITOR_EV_META_F1 ){ "\033OP", 32, 33 | (unsigned char)(1<<7) } | |||
1795 | ,DKEY("k2","kf2", "\033OQ", LINEEDITOR_EV_F2, LINEEDITOR_EV_META_F2 ){ "\033OQ", 34, 35 | (unsigned char)(1<<7) } | |||
1796 | ,DKEY("k3","kf3", "\033OR", LINEEDITOR_EV_F3, LINEEDITOR_EV_META_F3 ){ "\033OR", 36, 37 | (unsigned char)(1<<7) } | |||
1797 | ,DKEY("k4","kf4", "\033OS", LINEEDITOR_EV_F4, LINEEDITOR_EV_META_F4 ){ "\033OS", 38, 39 | (unsigned char)(1<<7) } | |||
1798 | #ifdef LINEEDITOR_SUPPORT_ALTERNATE_ESCAPES | |||
1799 | ,DKEY("kh","khome","\033OH", LINEEDITOR_EV_HOME, LINEEDITOR_EV_HOME_DOC ){ "\033OH", 24, 25 | (unsigned char)(1<<7) } | |||
1800 | ,DKEY("@7","kend", "\033OF", LINEEDITOR_EV_END, LINEEDITOR_EV_END_DOC ){ "\033OF", 30, 31 | (unsigned char)(1<<7) } | |||
1801 | ,DKEY("k1","kf1", "\033[11~",LINEEDITOR_EV_F1, LINEEDITOR_EV_META_F1 ){ "\033[11~", 32, 33 | (unsigned char)(1<<7) } | |||
1802 | ,DKEY("k2","kf2", "\033[12~",LINEEDITOR_EV_F2, LINEEDITOR_EV_META_F2 ){ "\033[12~", 34, 35 | (unsigned char)(1<<7) } | |||
1803 | ,DKEY("k3","kf3", "\033[13~",LINEEDITOR_EV_F3, LINEEDITOR_EV_META_F3 ){ "\033[13~", 36, 37 | (unsigned char)(1<<7) } | |||
1804 | ,DKEY("k4","kf4", "\033[14~",LINEEDITOR_EV_F4, LINEEDITOR_EV_META_F4 ){ "\033[14~", 38, 39 | (unsigned char)(1<<7) } | |||
1805 | #endif | |||
1806 | #ifdef LINEEDITOR_SUPPORT_F5_TO_F12 | |||
1807 | ,DKEY("k5","kf5", "\033[15~",LINEEDITOR_EV_F5, LINEEDITOR_EV_META_F5 ){ "\033[15~", 40, 41 | (unsigned char)(1<<7) } | |||
1808 | ,DKEY("k6","kf6", "\033[17~",LINEEDITOR_EV_F6, LINEEDITOR_EV_META_F6 ){ "\033[17~", 42, 43 | (unsigned char)(1<<7) } | |||
1809 | ,DKEY("k7","kf7", "\033[18~",LINEEDITOR_EV_F7, LINEEDITOR_EV_META_F7 ){ "\033[18~", 44, 45 | (unsigned char)(1<<7) } | |||
1810 | ,DKEY("k8","kf8", "\033[19~",LINEEDITOR_EV_F8, LINEEDITOR_EV_META_F8 ){ "\033[19~", 46, 47 | (unsigned char)(1<<7) } | |||
1811 | ,DKEY("k9","kf9", "\033[20~",LINEEDITOR_EV_F9, LINEEDITOR_EV_META_F9 ){ "\033[20~", 48, 49 | (unsigned char)(1<<7) } | |||
1812 | ,DKEY("k;","kf10", "\033[21~",LINEEDITOR_EV_F10, LINEEDITOR_EV_META_F10 ){ "\033[21~", 50, 51 | (unsigned char)(1<<7) } | |||
1813 | ,DKEY("F1","kf11", "\033[23~",LINEEDITOR_EV_F11, LINEEDITOR_EV_META_F11 ){ "\033[23~", 52, 53 | (unsigned char)(1<<7) } | |||
1814 | ,DKEY("F2","kf12", "\033[24~",LINEEDITOR_EV_F12, LINEEDITOR_EV_META_F12 ){ "\033[24~", 54, 55 | (unsigned char)(1<<7) } | |||
1815 | #endif | |||
1816 | }; | |||
1817 | ||||
1818 | ||||
1819 | ___HIDDENstatic ___SCMOBJlong lineeditor_dkey_install | |||
1820 | ___P((lineeditor_input_decoder *decoder,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1821 | char *cap,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1822 | ___U8 event_no_escape,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1823 | ___U8 event_with_escape,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1824 | ___BOOL force_xterm),(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1825 | (decoder,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1826 | cap,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1827 | event_no_escape,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1828 | event_with_escape,(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1829 | force_xterm)(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1830 | lineeditor_input_decoder *decoder;(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1831 | char *cap;(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1832 | ___U8 event_no_escape;(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1833 | ___U8 event_with_escape;(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1834 | ___BOOL force_xterm;)(lineeditor_input_decoder *decoder, char *cap, unsigned char event_no_escape , unsigned char event_with_escape, int force_xterm) | |||
1835 | { | |||
1836 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1837 | char *seq; | |||
1838 | ||||
1839 | #ifdef USE_TERMCAP_OR_TERMINFO | |||
1840 | ||||
1841 | if (!force_xterm) | |||
1842 | { | |||
1843 | #ifdef USE_TERMCAP | |||
1844 | ||||
1845 | seq = tgetstr (cap, NULL((void*)0)); | |||
1846 | ||||
1847 | #else | |||
1848 | ||||
1849 | seq = tigetstr (cap); | |||
1850 | ||||
1851 | #endif | |||
1852 | } | |||
1853 | else | |||
1854 | ||||
1855 | #endif | |||
1856 | ||||
1857 | seq = cap; | |||
1858 | ||||
1859 | if (seq != ___CAST(char*,-1)((char*)(-1)) && seq != NULL((void*)0)) | |||
1860 | if ((e = lineeditor_input_decoder_add (decoder, seq, event_no_escape)) | |||
1861 | != ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
1862 | event_with_escape != (LINEEDITOR_EV_NONE0|WITH_ESC_PREFIX(unsigned char)(1<<7))) | |||
1863 | e = lineeditor_input_decoder_add (decoder, seq, event_with_escape); | |||
1864 | ||||
1865 | return e; | |||
1866 | } | |||
1867 | ||||
1868 | ||||
1869 | ___HIDDENstatic ___SCMOBJlong lineeditor_dkey_install_table | |||
1870 | ___P((lineeditor_input_decoder *decoder,(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1871 | lineeditor_dkey *table,(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1872 | int len,(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1873 | ___BOOL force_xterm),(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1874 | (decoder,(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1875 | table,(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1876 | len,(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1877 | force_xterm)(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1878 | lineeditor_input_decoder *decoder;(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1879 | lineeditor_dkey *table;(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1880 | int len;(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1881 | ___BOOL force_xterm;)(lineeditor_input_decoder *decoder, lineeditor_dkey *table, int len, int force_xterm) | |||
1882 | { | |||
1883 | ___SCMOBJlong e; | |||
1884 | int i; | |||
1885 | ||||
1886 | for (i=0; i<len; i++) | |||
1887 | if ((e = lineeditor_dkey_install | |||
1888 | (decoder, | |||
1889 | table[i].cap, | |||
1890 | table[i].event_no_escape, | |||
1891 | table[i].event_with_escape, | |||
1892 | force_xterm)) | |||
1893 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1894 | return e; | |||
1895 | ||||
1896 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1897 | } | |||
1898 | ||||
1899 | ||||
1900 | #endif | |||
1901 | ||||
1902 | ||||
1903 | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | |||
1904 | ||||
1905 | ||||
1906 | ___HIDDENstatic ___SCMOBJlong lineeditor_input_decoder_init | |||
1907 | ___P((lineeditor_input_decoder *decoder,(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1908 | ___BOOL map_rubout_to_backspace,(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1909 | ___BOOL emacs_bindings,(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1910 | ___BOOL force_xterm),(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1911 | (decoder,(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1912 | map_rubout_to_backspace,(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1913 | emacs_bindings,(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1914 | force_xterm)(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1915 | lineeditor_input_decoder *decoder;(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1916 | ___BOOL map_rubout_to_backspace;(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1917 | ___BOOL emacs_bindings;(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1918 | ___BOOL force_xterm;)(lineeditor_input_decoder *decoder, int map_rubout_to_backspace , int emacs_bindings, int force_xterm) | |||
1919 | { | |||
1920 | ___SCMOBJlong e; | |||
1921 | ||||
1922 | decoder->length = 0; | |||
1923 | ||||
1924 | if ((e = lineeditor_defseq_install_table | |||
1925 | (decoder, | |||
1926 | lineeditor_defseq_common, | |||
1927 | ___NBELEMS(lineeditor_defseq_common)(sizeof (lineeditor_defseq_common) / sizeof ((lineeditor_defseq_common )[0])))) | |||
1928 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1929 | return e; | |||
1930 | ||||
1931 | if (map_rubout_to_backspace) | |||
1932 | if ((e = lineeditor_defseq_install_table | |||
1933 | (decoder, | |||
1934 | lineeditor_defseq_map_rubout_to_backspace, | |||
1935 | ___NBELEMS(lineeditor_defseq_map_rubout_to_backspace)(sizeof (lineeditor_defseq_map_rubout_to_backspace) / sizeof ( (lineeditor_defseq_map_rubout_to_backspace)[0])))) | |||
1936 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1937 | return e; | |||
1938 | ||||
1939 | if (emacs_bindings) | |||
1940 | if ((e = lineeditor_defseq_install_table | |||
1941 | (decoder, | |||
1942 | lineeditor_defseq_emacs, | |||
1943 | ___NBELEMS(lineeditor_defseq_emacs)(sizeof (lineeditor_defseq_emacs) / sizeof ((lineeditor_defseq_emacs )[0])))) | |||
1944 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1945 | return e; | |||
1946 | ||||
1947 | #ifdef USE_CURSES | |||
1948 | ||||
1949 | if ((e = lineeditor_dkey_install_table | |||
1950 | (decoder, | |||
1951 | lineeditor_dkey_table, | |||
1952 | ___NBELEMS(lineeditor_dkey_table)(sizeof (lineeditor_dkey_table) / sizeof ((lineeditor_dkey_table )[0])), | |||
1953 | force_xterm)) | |||
1954 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1955 | return e; | |||
1956 | ||||
1957 | #endif | |||
1958 | ||||
1959 | if ((e = lineeditor_defseq_install_table | |||
1960 | (decoder, | |||
1961 | lineeditor_defseq_widespread, | |||
1962 | ___NBELEMS(lineeditor_defseq_widespread)(sizeof (lineeditor_defseq_widespread) / sizeof ((lineeditor_defseq_widespread )[0])))) | |||
1963 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1964 | return e; | |||
1965 | ||||
1966 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
1967 | } | |||
1968 | ||||
1969 | ||||
1970 | /*---------------------------------------------------------------------------*/ | |||
1971 | ||||
1972 | /* Line editing history routines */ | |||
1973 | ||||
1974 | ||||
1975 | ___HIDDENstatic ___SCMOBJlong lineeditor_history_begin_edit | |||
1976 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history *h) | |||
1977 | lineeditor_history *h),(___device_tty *self, lineeditor_history *h) | |||
1978 | (self,(___device_tty *self, lineeditor_history *h) | |||
1979 | h)(___device_tty *self, lineeditor_history *h) | |||
1980 | ___device_tty *self;(___device_tty *self, lineeditor_history *h) | |||
1981 | lineeditor_history *h;)(___device_tty *self, lineeditor_history *h) | |||
1982 | { | |||
1983 | #define LINEEDITOR_FUDGE80 80 | |||
1984 | ||||
1985 | ___device_tty *d = self; | |||
1986 | ___SCMOBJlong e; | |||
1987 | ||||
1988 | if (h->edited.buffer == NULL((void*)0)) | |||
1989 | { | |||
1990 | if ((e = extensible_string_copy | |||
1991 | (h->actual.buffer, | |||
1992 | h->actual.length, | |||
1993 | &h->edited, | |||
1994 | LINEEDITOR_FUDGE80)) | |||
1995 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
1996 | return e; | |||
1997 | } | |||
1998 | ||||
1999 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2000 | } | |||
2001 | ||||
2002 | ||||
2003 | ___HIDDENstatic void lineeditor_history_end_edit | |||
2004 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history *h) | |||
2005 | lineeditor_history *h),(___device_tty *self, lineeditor_history *h) | |||
2006 | (self,(___device_tty *self, lineeditor_history *h) | |||
2007 | h)(___device_tty *self, lineeditor_history *h) | |||
2008 | ___device_tty *self;(___device_tty *self, lineeditor_history *h) | |||
2009 | lineeditor_history *h;)(___device_tty *self, lineeditor_history *h) | |||
2010 | { | |||
2011 | ___device_tty *d = self; | |||
2012 | ||||
2013 | if (h->edited.buffer != NULL((void*)0)) | |||
2014 | { | |||
2015 | extensible_string_cleanup (&h->edited); | |||
2016 | h->edited.buffer = NULL((void*)0); | |||
2017 | } | |||
2018 | } | |||
2019 | ||||
2020 | ||||
2021 | ___HIDDENstatic ___SCMOBJlong lineeditor_history_setup | |||
2022 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history **hist) | |||
2023 | lineeditor_history **hist),(___device_tty *self, lineeditor_history **hist) | |||
2024 | (self,(___device_tty *self, lineeditor_history **hist) | |||
2025 | hist)(___device_tty *self, lineeditor_history **hist) | |||
2026 | ___device_tty *self;(___device_tty *self, lineeditor_history **hist) | |||
2027 | lineeditor_history **hist;)(___device_tty *self, lineeditor_history **hist) | |||
2028 | { | |||
2029 | ___device_tty *d = self; | |||
2030 | ___SCMOBJlong e; | |||
2031 | lineeditor_history *h; | |||
2032 | ||||
2033 | h = ___CAST(lineeditor_history*,((lineeditor_history*)(___alloc_mem (sizeof (lineeditor_history )))) | |||
2034 | ___alloc_mem (sizeof (lineeditor_history)))((lineeditor_history*)(___alloc_mem (sizeof (lineeditor_history )))); | |||
2035 | ||||
2036 | if (h == NULL((void*)0)) | |||
2037 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
2038 | ||||
2039 | if ((e = extensible_string_setup (&h->actual, 0)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2040 | { | |||
2041 | ___free_mem (h); | |||
2042 | return e; | |||
2043 | } | |||
2044 | ||||
2045 | h->edited.buffer = NULL((void*)0); | |||
2046 | ||||
2047 | h->prev = h; /* create a circular list */ | |||
2048 | h->next = h; | |||
2049 | ||||
2050 | *hist = h; | |||
2051 | ||||
2052 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2053 | } | |||
2054 | ||||
2055 | ||||
2056 | ___HIDDENstatic ___SCMOBJlong lineeditor_history_cleanup | |||
2057 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history *h) | |||
2058 | lineeditor_history *h),(___device_tty *self, lineeditor_history *h) | |||
2059 | (self,(___device_tty *self, lineeditor_history *h) | |||
2060 | h)(___device_tty *self, lineeditor_history *h) | |||
2061 | ___device_tty *self;(___device_tty *self, lineeditor_history *h) | |||
2062 | lineeditor_history *h;)(___device_tty *self, lineeditor_history *h) | |||
2063 | { | |||
2064 | ___device_tty *d = self; | |||
2065 | ||||
2066 | lineeditor_history_end_edit (d, h); | |||
2067 | ||||
2068 | extensible_string_cleanup (&h->actual); | |||
2069 | ||||
2070 | ___free_mem (h); | |||
2071 | ||||
2072 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2073 | } | |||
2074 | ||||
2075 | ||||
2076 | ___HIDDENstatic void lineeditor_history_remove | |||
2077 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history *item) | |||
2078 | lineeditor_history *item),(___device_tty *self, lineeditor_history *item) | |||
2079 | (self,(___device_tty *self, lineeditor_history *item) | |||
2080 | item)(___device_tty *self, lineeditor_history *item) | |||
2081 | ___device_tty *self;(___device_tty *self, lineeditor_history *item) | |||
2082 | lineeditor_history *item;)(___device_tty *self, lineeditor_history *item) | |||
2083 | { | |||
2084 | ___device_tty *d = self; | |||
2085 | ||||
2086 | lineeditor_history *prev = item->prev; | |||
2087 | lineeditor_history *next = item->next; | |||
2088 | ||||
2089 | if (prev == item) | |||
2090 | d->hist_last = NULL((void*)0); | |||
2091 | else | |||
2092 | { | |||
2093 | next->prev = prev; | |||
2094 | prev->next = next; | |||
2095 | item->prev = item; | |||
2096 | item->next = item; | |||
2097 | if (d->hist_last == item) | |||
2098 | d->hist_last = prev; | |||
2099 | } | |||
2100 | } | |||
2101 | ||||
2102 | ||||
2103 | ___HIDDENstatic void lineeditor_history_trim_to | |||
2104 | ___P((___device_tty *self,(___device_tty *self, int max_length) | |||
2105 | int max_length),(___device_tty *self, int max_length) | |||
2106 | (self,(___device_tty *self, int max_length) | |||
2107 | max_length)(___device_tty *self, int max_length) | |||
2108 | ___device_tty *self;(___device_tty *self, int max_length) | |||
2109 | int max_length;)(___device_tty *self, int max_length) | |||
2110 | { | |||
2111 | ___device_tty *d = self; | |||
2112 | ||||
2113 | while (d->history_length > max_length) | |||
2114 | { | |||
2115 | lineeditor_history *first = d->hist_last->next; | |||
2116 | lineeditor_history_remove (d, first); | |||
2117 | lineeditor_history_cleanup (d, first); /* ignore error */ | |||
2118 | d->history_length--; | |||
2119 | } | |||
2120 | } | |||
2121 | ||||
2122 | ||||
2123 | ___HIDDENstatic void lineeditor_history_trim | |||
2124 | ___P((___device_tty *self),(___device_tty *self) | |||
2125 | (self)(___device_tty *self) | |||
2126 | ___device_tty *self;)(___device_tty *self) | |||
2127 | { | |||
2128 | ___device_tty *d = self; | |||
2129 | ||||
2130 | lineeditor_history_trim_to (d, d->history_max_length); | |||
2131 | } | |||
2132 | ||||
2133 | ||||
2134 | ___HIDDENstatic void lineeditor_set_history_max_length | |||
2135 | ___P((___device_tty *self,(___device_tty *self, int history_max_length) | |||
2136 | int history_max_length),(___device_tty *self, int history_max_length) | |||
2137 | (self,(___device_tty *self, int history_max_length) | |||
2138 | history_max_length)(___device_tty *self, int history_max_length) | |||
2139 | ___device_tty *self;(___device_tty *self, int history_max_length) | |||
2140 | int history_max_length;)(___device_tty *self, int history_max_length) | |||
2141 | { | |||
2142 | ___device_tty *d = self; | |||
2143 | ||||
2144 | if (history_max_length >= 0) | |||
2145 | { | |||
2146 | d->history_max_length = history_max_length; | |||
2147 | lineeditor_history_trim (d); | |||
2148 | } | |||
2149 | } | |||
2150 | ||||
2151 | ||||
2152 | ___HIDDENstatic void lineeditor_history_add_after | |||
2153 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2154 | lineeditor_history *item,(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2155 | lineeditor_history *dest),(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2156 | (self,(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2157 | item,(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2158 | dest)(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2159 | ___device_tty *self;(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2160 | lineeditor_history *item;(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2161 | lineeditor_history *dest;)(___device_tty *self, lineeditor_history *item, lineeditor_history *dest) | |||
2162 | { | |||
2163 | ___device_tty *d = self; | |||
2164 | ||||
2165 | if (dest == NULL((void*)0)) | |||
2166 | { | |||
2167 | item->prev = item; | |||
2168 | item->next = item; | |||
2169 | } | |||
2170 | else | |||
2171 | { | |||
2172 | lineeditor_history *after_dest = dest->next; | |||
2173 | item->next = after_dest; | |||
2174 | item->prev = dest; | |||
2175 | dest->next = item; | |||
2176 | after_dest->prev = item; | |||
2177 | } | |||
2178 | ||||
2179 | d->history_length++; | |||
2180 | } | |||
2181 | ||||
2182 | ||||
2183 | ___HIDDENstatic void lineeditor_history_add_last | |||
2184 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history *item) | |||
2185 | lineeditor_history *item),(___device_tty *self, lineeditor_history *item) | |||
2186 | (self,(___device_tty *self, lineeditor_history *item) | |||
2187 | item)(___device_tty *self, lineeditor_history *item) | |||
2188 | ___device_tty *self;(___device_tty *self, lineeditor_history *item) | |||
2189 | lineeditor_history *item;)(___device_tty *self, lineeditor_history *item) | |||
2190 | { | |||
2191 | ___device_tty *d = self; | |||
2192 | ||||
2193 | lineeditor_history_add_after (d, item, d->hist_last); | |||
2194 | d->hist_last = item; | |||
2195 | } | |||
2196 | ||||
2197 | ||||
2198 | ___HIDDENstatic ___SCMOBJlong lineeditor_history_add_line_before_last | |||
2199 | ___P((___device_tty *self,(___device_tty *self, int len, extensible_string_char *chars) | |||
2200 | int len,(___device_tty *self, int len, extensible_string_char *chars) | |||
2201 | extensible_string_char *chars),(___device_tty *self, int len, extensible_string_char *chars) | |||
2202 | (self,(___device_tty *self, int len, extensible_string_char *chars) | |||
2203 | len,(___device_tty *self, int len, extensible_string_char *chars) | |||
2204 | chars)(___device_tty *self, int len, extensible_string_char *chars) | |||
2205 | ___device_tty *self;(___device_tty *self, int len, extensible_string_char *chars) | |||
2206 | int len;(___device_tty *self, int len, extensible_string_char *chars) | |||
2207 | extensible_string_char *chars;)(___device_tty *self, int len, extensible_string_char *chars) | |||
2208 | { | |||
2209 | ___SCMOBJlong e; | |||
2210 | lineeditor_history *line; | |||
2211 | ||||
2212 | if ((e = lineeditor_history_setup (self, &line)) | |||
2213 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2214 | { | |||
2215 | if ((e = extensible_string_insert_at_end (&line->actual, len, chars)) | |||
2216 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2217 | lineeditor_history_add_after (self, line, self->hist_last->prev); | |||
2218 | else | |||
2219 | lineeditor_history_cleanup (self, line); /* ignore error */ | |||
2220 | } | |||
2221 | ||||
2222 | return e; | |||
2223 | } | |||
2224 | ||||
2225 | ||||
2226 | /*---------------------------------------------------------------------------*/ | |||
2227 | ||||
2228 | /* Line editing routines */ | |||
2229 | ||||
2230 | ||||
2231 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_drain | |||
2232 | ___P((___device_tty *self),(___device_tty *self) | |||
2233 | (self)(___device_tty *self) | |||
2234 | ___device_tty *self;)(___device_tty *self) | |||
2235 | { | |||
2236 | /* | |||
2237 | * This routine drains the output buffers. The return value is | |||
2238 | * ___FIX(___NO_ERR) if and only if the output buffers were | |||
2239 | * completely drained. The return value is different from | |||
2240 | * ___FIX(___NO_ERR) only when ___device_tty_write | |||
2241 | * returned an error. | |||
2242 | */ | |||
2243 | ||||
2244 | ___device_tty *d = self; | |||
2245 | ___SCMOBJlong e; | |||
2246 | ||||
2247 | for (;;) | |||
2248 | { | |||
2249 | int byte_avail; | |||
2250 | int len = d->output_byte_hi - d->output_byte_lo; | |||
2251 | ||||
2252 | while (len > 0) | |||
2253 | { | |||
2254 | ___stream_index len_done; | |||
2255 | ___U8unsigned char *byte_buf = d->output_byte + d->output_byte_lo; | |||
2256 | ||||
2257 | if ((e = ___device_tty_write | |||
2258 | (d, | |||
2259 | byte_buf, | |||
2260 | len, | |||
2261 | &len_done)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2262 | return e; | |||
2263 | ||||
2264 | len = d->output_byte_hi - (d->output_byte_lo += len_done); | |||
| ||||
2265 | } | |||
2266 | ||||
2267 | d->output_byte_lo = 0; | |||
2268 | d->output_byte_hi = 0; | |||
2269 | ||||
2270 | len = d->output_char.length - d->output_char_lo; | |||
2271 | ||||
2272 | if (len <= 0) | |||
2273 | break; | |||
2274 | ||||
2275 | do | |||
2276 | { | |||
2277 | ___Cunsigned int *char_buf = d->output_char.buffer + d->output_char_lo; | |||
2278 | ___U8unsigned char *byte_buf = d->output_byte + d->output_byte_hi; | |||
2279 | ||||
2280 | byte_avail = ___NBELEMS(d->output_byte)(sizeof (d->output_byte) / sizeof ((d->output_byte)[0]) ) - d->output_byte_hi; | |||
2281 | ||||
2282 | if (chars_to_bytes (char_buf, | |||
2283 | &len, | |||
2284 | byte_buf, | |||
2285 | &byte_avail, | |||
2286 | &d->output_encoding_state) | |||
2287 | == ___ILLEGAL_CHAR2) | |||
2288 | len--; /* skip over the illegal character */ | |||
2289 | ||||
2290 | #ifdef ___DEBUG_TTY | |||
2291 | ||||
2292 | { | |||
2293 | int i; | |||
2294 | int n = (___NBELEMS(d->output_byte)(sizeof (d->output_byte) / sizeof ((d->output_byte)[0]) ) - d->output_byte_hi) - byte_avail; | |||
2295 | ||||
2296 | ___printf ("lineeditor_output_drain nb_bytes: %d ", n); | |||
2297 | ||||
2298 | for (i=0; i<n; i++) | |||
2299 | ___printf (" %02x", d->output_byte[i]); | |||
2300 | ||||
2301 | ___printf ("\n"); | |||
2302 | } | |||
2303 | ||||
2304 | #endif | |||
2305 | ||||
2306 | d->output_char_lo = d->output_char.length - len; | |||
2307 | ||||
2308 | d->output_byte_hi = ___NBELEMS(d->output_byte)(sizeof (d->output_byte) / sizeof ((d->output_byte)[0]) ) - byte_avail; | |||
2309 | } while (byte_avail > 0 && len > 0); | |||
2310 | ||||
2311 | if (len <= 0) | |||
2312 | { | |||
2313 | extensible_string_set_length | |||
2314 | (&d->output_char, 0, 1); /* ignore error */ | |||
2315 | d->output_char.length = 0; /* in case set_length failed */ | |||
2316 | d->output_char_lo = 0; | |||
2317 | } | |||
2318 | } | |||
2319 | ||||
2320 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2321 | } | |||
2322 | ||||
2323 | ||||
2324 | /* forward declaration needed because lineeditor_output is recursive */ | |||
2325 | ||||
2326 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_emulate | |||
2327 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, int len) | |||
2328 | ___C *buf,(___device_tty *self, unsigned int *buf, int len) | |||
2329 | int len),(___device_tty *self, unsigned int *buf, int len) | |||
2330 | ())(___device_tty *self, unsigned int *buf, int len); | |||
2331 | ||||
2332 | ||||
2333 | ___HIDDENstatic ___SCMOBJlong lineeditor_output | |||
2334 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, int len) | |||
2335 | ___C *buf,(___device_tty *self, unsigned int *buf, int len) | |||
2336 | int len),(___device_tty *self, unsigned int *buf, int len) | |||
2337 | (self,(___device_tty *self, unsigned int *buf, int len) | |||
2338 | buf,(___device_tty *self, unsigned int *buf, int len) | |||
2339 | len)(___device_tty *self, unsigned int *buf, int len) | |||
2340 | ___device_tty *self;(___device_tty *self, unsigned int *buf, int len) | |||
2341 | ___C *buf;(___device_tty *self, unsigned int *buf, int len) | |||
2342 | int len;)(___device_tty *self, unsigned int *buf, int len) | |||
2343 | { | |||
2344 | /* | |||
2345 | * This routine outputs the string of characters "buf" of length | |||
2346 | * "len" to the terminal. | |||
2347 | */ | |||
2348 | ||||
2349 | ___device_tty *d = self; | |||
2350 | ___SCMOBJlong e; | |||
2351 | ||||
2352 | #ifdef ___DEBUG_TTY | |||
2353 | ||||
2354 | { | |||
2355 | int i; | |||
2356 | ||||
2357 | ___printf ("et:%d row:%2d col:%2d cursor:%2d dw:%d len:%3d ", | |||
2358 | d->emulate_terminal, | |||
2359 | d->terminal_row, | |||
2360 | d->terminal_col, | |||
2361 | d->terminal_cursor, | |||
2362 | d->terminal_delayed_wrap, | |||
2363 | len); | |||
2364 | ||||
2365 | ___printf ("\""); | |||
2366 | ||||
2367 | for (i=0; i<len; i++) | |||
2368 | if (buf[i] < 32 || buf[i] >= 127) | |||
2369 | ___printf ("\\x%02x", buf[i]); | |||
2370 | else | |||
2371 | ___printf ("%c", buf[i]); | |||
2372 | ||||
2373 | ___printf ("\"\n"); | |||
2374 | } | |||
2375 | ||||
2376 | #endif | |||
2377 | ||||
2378 | if (d->emulate_terminal) | |||
2379 | { | |||
2380 | d->emulate_terminal = 0; | |||
2381 | e = lineeditor_output_terminal_emulate (d, buf, len); | |||
2382 | d->emulate_terminal = 1; | |||
2383 | } | |||
2384 | else | |||
2385 | e = extensible_string_insert | |||
2386 | (&d->output_char, | |||
2387 | d->output_char.length, | |||
2388 | len, | |||
2389 | buf); | |||
2390 | ||||
2391 | #ifdef USE_WIN32 | |||
2392 | e = lineeditor_output_drain (d);/******************************/ | |||
2393 | #endif | |||
2394 | ||||
2395 | return e; | |||
2396 | } | |||
2397 | ||||
2398 | ||||
2399 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_curses_drain | |||
2400 | ___P((int len),(int len) | |||
2401 | (len)(int len) | |||
2402 | int len;)(int len) | |||
2403 | { | |||
2404 | /* | |||
2405 | * This routine drains the curses output buffer. The parameters it | |||
2406 | * uses are stored in the TTY module structure "___tty_mod" (because | |||
2407 | * C does not have closures...). | |||
2408 | */ | |||
2409 | ||||
2410 | struct ___curses_struct *cs = &CURRENT_CURSES_STRUCT___tty_mod.curses[___tty_mod.curses_tty->emulate_terminal]; | |||
2411 | ||||
2412 | return lineeditor_output (___tty_mod.curses_tty, cs->output, len); | |||
2413 | } | |||
2414 | ||||
2415 | ||||
2416 | ___HIDDENstatic int lineeditor_output_curses | |||
2417 | ___P((int c),(int c) | |||
2418 | (c)(int c) | |||
2419 | int c;)(int c) | |||
2420 | { | |||
2421 | /* | |||
2422 | * This routine outputs a C character. It is passed as an argument | |||
2423 | * to the termcap/terminfo "tputs" routine for outputing individual | |||
2424 | * characters. The parameters it uses are stored in the TTY module | |||
2425 | * structure "___tty_mod" (because C does not have closures...). | |||
2426 | */ | |||
2427 | ||||
2428 | struct ___curses_struct *cs = &CURRENT_CURSES_STRUCT___tty_mod.curses[___tty_mod.curses_tty->emulate_terminal]; | |||
2429 | ||||
2430 | if (cs->last_err == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2431 | { | |||
2432 | cs->output[cs->output_lo++] = c; | |||
2433 | ||||
2434 | if (cs->output_lo >= ___CAST(int,___NBELEMS(cs->output))((int)((sizeof (cs->output) / sizeof ((cs->output)[0])) ))) | |||
2435 | { | |||
2436 | cs->last_err = lineeditor_output_curses_drain | |||
2437 | (___NBELEMS(cs->output)(sizeof (cs->output) / sizeof ((cs->output)[0]))); | |||
2438 | cs->output_lo = 0; | |||
2439 | } | |||
2440 | } | |||
2441 | ||||
2442 | return c; | |||
2443 | } | |||
2444 | ||||
2445 | ||||
2446 | ___HIDDENstatic char *lineeditor_cap | |||
2447 | ___P((___device_tty *self,(___device_tty *self, int cap) | |||
2448 | int cap),(___device_tty *self, int cap) | |||
2449 | (self,(___device_tty *self, int cap) | |||
2450 | cap)(___device_tty *self, int cap) | |||
2451 | ___device_tty *self;(___device_tty *self, int cap) | |||
2452 | int cap;)(___device_tty *self, int cap) | |||
2453 | { | |||
2454 | /* | |||
2455 | * This routine returns the curses string for the terminal | |||
2456 | * capability "cap". | |||
2457 | */ | |||
2458 | ||||
2459 | ___device_tty *d = self; | |||
2460 | ||||
2461 | #ifdef TERMINAL_EMULATION_USES_CURSES | |||
2462 | ||||
2463 | if (!d->emulate_terminal) | |||
2464 | return d->capability[cap]; | |||
2465 | ||||
2466 | #endif | |||
2467 | ||||
2468 | #ifdef USE_TERMCAP_OR_TERMINFO | |||
2469 | ||||
2470 | return lineeditor_dcap_table[cap].xterm_cap; | |||
2471 | ||||
2472 | #else | |||
2473 | ||||
2474 | return lineeditor_dcap_table[cap].cap; | |||
2475 | ||||
2476 | #endif | |||
2477 | } | |||
2478 | ||||
2479 | ||||
2480 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_cap3 | |||
2481 | ___P((___device_tty *self,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2482 | int cap,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2483 | int arg1,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2484 | int arg2,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2485 | int arg3,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2486 | int rep),(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2487 | (self,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2488 | cap,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2489 | arg1,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2490 | arg2,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2491 | arg3,(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2492 | rep)(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2493 | ___device_tty *self;(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2494 | int cap;(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2495 | int arg1;(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2496 | int arg2;(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2497 | int arg3;(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2498 | int rep;)(___device_tty *self, int cap, int arg1, int arg2, int arg3, int rep) | |||
2499 | { | |||
2500 | /* | |||
2501 | * This routine outputs the character sequence for the terminal | |||
2502 | * capability "cap" with integer parameters "arg1", "arg2" and "arg3" | |||
2503 | * (-1 means no parameter). This is repeated "rep" times. | |||
2504 | */ | |||
2505 | ||||
2506 | ___device_tty *d = self; | |||
2507 | struct ___curses_struct *cs; | |||
2508 | char *str = lineeditor_cap (d, cap); | |||
2509 | ||||
2510 | if (str == NULL((void*)0)) | |||
2511 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2512 | ||||
2513 | ___tty_mod.curses_tty = d; | |||
2514 | ||||
2515 | cs = &CURRENT_CURSES_STRUCT___tty_mod.curses[___tty_mod.curses_tty->emulate_terminal]; | |||
2516 | cs->output_lo = 0; | |||
2517 | cs->last_err = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2518 | ||||
2519 | while (rep > 0) | |||
2520 | { | |||
2521 | char *p; | |||
2522 | ||||
2523 | if (cap < LINEEDITOR_CAP_SGR09) /******** TODO: this belongs elsewhere */ | |||
2524 | d->terminal_delayed_wrap = 0; /* cursor cmds cancel delayed wrap */ | |||
2525 | ||||
2526 | #ifdef TERMINAL_EMULATION_USES_CURSES | |||
2527 | #ifdef USE_TERMCAP_OR_TERMINFO | |||
2528 | ||||
2529 | if (!d->emulate_terminal) | |||
2530 | { | |||
2531 | p = str; | |||
2532 | ||||
2533 | if (arg1 >= 0 && arg3 < 0) | |||
2534 | { | |||
2535 | #ifdef USE_TERMCAP | |||
2536 | p = tgoto (p, arg2, arg1); | |||
2537 | #else | |||
2538 | if (arg2 >= 0) | |||
2539 | p = tparm (p, arg1, arg2); | |||
2540 | else | |||
2541 | p = tparm (p, arg1); | |||
2542 | #endif | |||
2543 | } | |||
2544 | ||||
2545 | if (tputs (p, 1, lineeditor_output_curses) == ERR && | |||
2546 | cs->last_err == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2547 | cs->last_err = ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
2548 | } | |||
2549 | else | |||
2550 | ||||
2551 | #endif | |||
2552 | #endif | |||
2553 | ||||
2554 | { | |||
2555 | int params[3]; | |||
2556 | int stack[10]; | |||
2557 | int sp = 0; | |||
2558 | ||||
2559 | params[0] = arg1; | |||
2560 | params[1] = arg2; | |||
2561 | params[2] = arg3; | |||
2562 | ||||
2563 | p = str; | |||
2564 | ||||
2565 | while (*p != '\0') | |||
2566 | { | |||
2567 | ___Cunsigned int c = *p++; | |||
2568 | ||||
2569 | if (c == '%') /* start of a formatting command? */ | |||
2570 | { | |||
2571 | switch (*p++) | |||
2572 | { | |||
2573 | case 'i': | |||
2574 | params[0]++; | |||
2575 | params[1]++; | |||
2576 | break; | |||
2577 | ||||
2578 | case 'p': | |||
2579 | if (sp < ___CAST(int,___NBELEMS(stack))((int)((sizeof (stack) / sizeof ((stack)[0]))))) | |||
2580 | stack[sp++] = params[*p++ - '1']; | |||
2581 | break; | |||
2582 | ||||
2583 | case 'd': | |||
2584 | { | |||
2585 | int d = 1; | |||
2586 | int n; | |||
2587 | ||||
2588 | if (sp > 0) | |||
2589 | n = stack[--sp]; | |||
2590 | else | |||
2591 | n = 0; | |||
2592 | ||||
2593 | while (d*10 <= n) | |||
2594 | d *= 10; | |||
2595 | ||||
2596 | while (d > 0) | |||
2597 | { | |||
2598 | lineeditor_output_curses ('0' + (n / d) % 10); | |||
2599 | d /= 10; | |||
2600 | } | |||
2601 | ||||
2602 | break; | |||
2603 | } | |||
2604 | } | |||
2605 | } | |||
2606 | else | |||
2607 | lineeditor_output_curses (c); | |||
2608 | } | |||
2609 | } | |||
2610 | ||||
2611 | if (cs->last_err != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2612 | return cs->last_err; | |||
2613 | ||||
2614 | rep--; | |||
2615 | } | |||
2616 | ||||
2617 | return lineeditor_output_curses_drain (cs->output_lo); | |||
2618 | } | |||
2619 | ||||
2620 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_cap0 | |||
2621 | ___P((___device_tty *self,(___device_tty *self, int cap, int rep) | |||
2622 | int cap,(___device_tty *self, int cap, int rep) | |||
2623 | int rep),(___device_tty *self, int cap, int rep) | |||
2624 | (self,(___device_tty *self, int cap, int rep) | |||
2625 | cap,(___device_tty *self, int cap, int rep) | |||
2626 | rep)(___device_tty *self, int cap, int rep) | |||
2627 | ___device_tty *self;(___device_tty *self, int cap, int rep) | |||
2628 | int cap;(___device_tty *self, int cap, int rep) | |||
2629 | int rep;)(___device_tty *self, int cap, int rep) | |||
2630 | { | |||
2631 | return lineeditor_output_cap3 (self, cap, -1, -1, -1, rep); | |||
2632 | } | |||
2633 | ||||
2634 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_cap1 | |||
2635 | ___P((___device_tty *self,(___device_tty *self, int cap, int arg1, int rep) | |||
2636 | int cap,(___device_tty *self, int cap, int arg1, int rep) | |||
2637 | int arg1,(___device_tty *self, int cap, int arg1, int rep) | |||
2638 | int rep),(___device_tty *self, int cap, int arg1, int rep) | |||
2639 | (self,(___device_tty *self, int cap, int arg1, int rep) | |||
2640 | cap,(___device_tty *self, int cap, int arg1, int rep) | |||
2641 | arg1,(___device_tty *self, int cap, int arg1, int rep) | |||
2642 | rep)(___device_tty *self, int cap, int arg1, int rep) | |||
2643 | ___device_tty *self;(___device_tty *self, int cap, int arg1, int rep) | |||
2644 | int cap;(___device_tty *self, int cap, int arg1, int rep) | |||
2645 | int arg1;(___device_tty *self, int cap, int arg1, int rep) | |||
2646 | int rep;)(___device_tty *self, int cap, int arg1, int rep) | |||
2647 | { | |||
2648 | return lineeditor_output_cap3 (self, cap, arg1, -1, -1, rep); | |||
2649 | } | |||
2650 | ||||
2651 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_cap2 | |||
2652 | ___P((___device_tty *self,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2653 | int cap,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2654 | int arg1,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2655 | int arg2,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2656 | int rep),(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2657 | (self,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2658 | cap,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2659 | arg1,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2660 | arg2,(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2661 | rep)(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2662 | ___device_tty *self;(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2663 | int cap;(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2664 | int arg1;(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2665 | int arg2;(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2666 | int rep;)(___device_tty *self, int cap, int arg1, int arg2, int rep) | |||
2667 | { | |||
2668 | return lineeditor_output_cap3 (self, cap, arg1, arg2, -1, rep); | |||
2669 | } | |||
2670 | ||||
2671 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_set_attrs | |||
2672 | ___P((___device_tty *self,(___device_tty *self, tty_text_attrs attrs) | |||
2673 | tty_text_attrs attrs),(___device_tty *self, tty_text_attrs attrs) | |||
2674 | (self,(___device_tty *self, tty_text_attrs attrs) | |||
2675 | attrs)(___device_tty *self, tty_text_attrs attrs) | |||
2676 | ___device_tty *self;(___device_tty *self, tty_text_attrs attrs) | |||
2677 | tty_text_attrs attrs;)(___device_tty *self, tty_text_attrs attrs) | |||
2678 | { | |||
2679 | /* | |||
2680 | * This routine outputs the character sequence that sets the text | |||
2681 | * attributes of the next characters sent to the terminal. | |||
2682 | */ | |||
2683 | ||||
2684 | ___device_tty *d = self; | |||
2685 | ___SCMOBJlong e; | |||
2686 | int turn_on; | |||
2687 | tty_text_attrs current_attrs; | |||
2688 | ||||
2689 | #ifdef TERMINAL_EMULATION_USES_CURSES | |||
2690 | ||||
2691 | if (!d->emulate_terminal) | |||
2692 | { | |||
2693 | current_attrs = d->terminal_attrs; | |||
2694 | d->terminal_attrs = attrs; | |||
2695 | } | |||
2696 | else | |||
2697 | ||||
2698 | #endif | |||
2699 | ||||
2700 | { | |||
2701 | current_attrs = d->current.attrs; | |||
2702 | d->current.attrs = attrs; | |||
2703 | } | |||
2704 | ||||
2705 | if (current_attrs == attrs) | |||
2706 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2707 | ||||
2708 | turn_on = GET_STYLE(attrs)(((attrs)>>8)&3); | |||
2709 | ||||
2710 | if ((GET_STYLE(current_attrs)(((current_attrs)>>8)&3) & ~turn_on) != 0 || | |||
2711 | (GET_FOREGROUND_COLOR(attrs)((attrs)&15) >= DEFAULT_TEXT_COLOR8 && | |||
2712 | GET_FOREGROUND_COLOR(current_attrs)((current_attrs)&15) < DEFAULT_TEXT_COLOR8) || | |||
2713 | (GET_BACKGROUND_COLOR(attrs)(((attrs)>>4)&15) >= DEFAULT_TEXT_COLOR8 && | |||
2714 | GET_BACKGROUND_COLOR(current_attrs)(((current_attrs)>>4)&15) < DEFAULT_TEXT_COLOR8)) | |||
2715 | { | |||
2716 | if ((e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_SGR09, 1)) | |||
2717 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2718 | return e; | |||
2719 | current_attrs = MAKE_TEXT_ATTRS(0,DEFAULT_TEXT_COLOR,DEFAULT_TEXT_COLOR)(((0)<<8)+(8)+((8)<<4)); | |||
2720 | } | |||
2721 | else | |||
2722 | turn_on = (~GET_STYLE(current_attrs)(((current_attrs)>>8)&3) & turn_on); | |||
2723 | ||||
2724 | if (turn_on & TEXT_STYLE_BOLD1) | |||
2725 | if ((e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_BOLD10, 1)) | |||
2726 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2727 | return e; | |||
2728 | ||||
2729 | if (turn_on & TEXT_STYLE_UNDERLINE2) | |||
2730 | if ((e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_SMUL11, 1)) | |||
2731 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2732 | return e; | |||
2733 | ||||
2734 | if (turn_on & TEXT_STYLE_REVERSE4) | |||
2735 | if ((e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_REV12, 1)) | |||
2736 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2737 | return e; | |||
2738 | ||||
2739 | if (GET_FOREGROUND_COLOR(attrs)((attrs)&15) < DEFAULT_TEXT_COLOR8 && | |||
2740 | GET_FOREGROUND_COLOR(attrs)((attrs)&15) != GET_FOREGROUND_COLOR(current_attrs)((current_attrs)&15)) | |||
2741 | if ((e = lineeditor_output_cap1 | |||
2742 | (d, | |||
2743 | LINEEDITOR_CAP_SETAF13, | |||
2744 | GET_FOREGROUND_COLOR(attrs)((attrs)&15), | |||
2745 | 1)) | |||
2746 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2747 | return e; | |||
2748 | ||||
2749 | if (GET_BACKGROUND_COLOR(attrs)(((attrs)>>4)&15) < DEFAULT_TEXT_COLOR8 && | |||
2750 | GET_BACKGROUND_COLOR(attrs)(((attrs)>>4)&15) != GET_BACKGROUND_COLOR(current_attrs)(((current_attrs)>>4)&15)) | |||
2751 | if ((e = lineeditor_output_cap1 | |||
2752 | (d, | |||
2753 | LINEEDITOR_CAP_SETAB14, | |||
2754 | GET_BACKGROUND_COLOR(attrs)(((attrs)>>4)&15), | |||
2755 | 1)) | |||
2756 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
2757 | return e; | |||
2758 | ||||
2759 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2760 | } | |||
2761 | ||||
2762 | ||||
2763 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_plain_chars | |||
2764 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, int len) | |||
2765 | ___C *buf,(___device_tty *self, unsigned int *buf, int len) | |||
2766 | int len),(___device_tty *self, unsigned int *buf, int len) | |||
2767 | (self,(___device_tty *self, unsigned int *buf, int len) | |||
2768 | buf,(___device_tty *self, unsigned int *buf, int len) | |||
2769 | len)(___device_tty *self, unsigned int *buf, int len) | |||
2770 | ___device_tty *self;(___device_tty *self, unsigned int *buf, int len) | |||
2771 | ___C *buf;(___device_tty *self, unsigned int *buf, int len) | |||
2772 | int len;)(___device_tty *self, unsigned int *buf, int len) | |||
2773 | { | |||
2774 | /* | |||
2775 | * This routine processes a string of plain characters (with no | |||
2776 | * control characters) that the emulated terminal received. It also | |||
2777 | * tracks the movement of the emulated terminal's cursor. | |||
2778 | */ | |||
2779 | ||||
2780 | ___device_tty *d = self; | |||
2781 | int col = d->terminal_col + d->terminal_delayed_wrap + len; | |||
2782 | ||||
2783 | if (col >= d->terminal_nb_cols) | |||
2784 | { | |||
2785 | if (d->has_auto_right_margin) | |||
2786 | { | |||
2787 | int row = d->terminal_row + col / d->terminal_nb_cols; | |||
2788 | ||||
2789 | col = col % d->terminal_nb_cols; | |||
2790 | ||||
2791 | if (col == 0 && d->has_eat_newline_glitch) | |||
2792 | { | |||
2793 | col = d->terminal_nb_cols - 1; | |||
2794 | row--; | |||
2795 | d->terminal_delayed_wrap = 1; /* delay wrap */ | |||
2796 | } | |||
2797 | else | |||
2798 | d->terminal_delayed_wrap = 0; | |||
2799 | ||||
2800 | if (row >= d->terminal_nb_rows) | |||
2801 | { | |||
2802 | d->current.line_start -= d->terminal_nb_cols * | |||
2803 | (row - d->terminal_nb_rows + 1); | |||
2804 | row = d->terminal_nb_rows - 1; | |||
2805 | } | |||
2806 | ||||
2807 | d->terminal_row = row; | |||
2808 | } | |||
2809 | else | |||
2810 | col = d->terminal_nb_cols - 1; | |||
2811 | } | |||
2812 | else | |||
2813 | d->terminal_delayed_wrap = 0; | |||
2814 | ||||
2815 | d->terminal_col = col; | |||
2816 | ||||
2817 | d->terminal_cursor = d->terminal_row * d->terminal_nb_cols + col; | |||
2818 | ||||
2819 | return lineeditor_output (d, buf, len); | |||
2820 | } | |||
2821 | ||||
2822 | ||||
2823 | #ifdef USE_WIN32 | |||
2824 | ||||
2825 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_op_move_abs | |||
2826 | ___P((___device_tty *self,(___device_tty *self, int dest_col, int dest_row) | |||
2827 | int dest_col,(___device_tty *self, int dest_col, int dest_row) | |||
2828 | int dest_row),(___device_tty *self, int dest_col, int dest_row) | |||
2829 | ())(___device_tty *self, int dest_col, int dest_row); | |||
2830 | ||||
2831 | #endif | |||
2832 | ||||
2833 | ||||
2834 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_op_move_col | |||
2835 | ___P((___device_tty *self,(___device_tty *self, int dist) | |||
2836 | int dist),(___device_tty *self, int dist) | |||
2837 | (self,(___device_tty *self, int dist) | |||
2838 | dist)(___device_tty *self, int dist) | |||
2839 | ___device_tty *self;(___device_tty *self, int dist) | |||
2840 | int dist;)(___device_tty *self, int dist) | |||
2841 | { | |||
2842 | /* | |||
2843 | * This routine performs a relative cursor positioning operation | |||
2844 | * that changes the column of the cursor. It also tracks the | |||
2845 | * movement of the emulated terminal's cursor. | |||
2846 | */ | |||
2847 | ||||
2848 | ___device_tty *d = self; | |||
2849 | int col = d->terminal_col; | |||
2850 | int dest_col = col + dist; | |||
2851 | ||||
2852 | if (dest_col < 0) | |||
2853 | dest_col = 0; | |||
2854 | else if (dest_col >= d->terminal_nb_cols) | |||
2855 | dest_col = d->terminal_nb_cols - 1; | |||
2856 | ||||
2857 | #ifdef USE_WIN32 | |||
2858 | ||||
2859 | return lineeditor_output_terminal_op_move_abs | |||
2860 | (d, | |||
2861 | dest_col, | |||
2862 | d->terminal_row); | |||
2863 | ||||
2864 | #else | |||
2865 | ||||
2866 | dist = dest_col - col; | |||
2867 | ||||
2868 | if (dist != 0) | |||
2869 | { | |||
2870 | d->terminal_col = dest_col; | |||
2871 | d->terminal_cursor = d->terminal_row * d->terminal_nb_cols + dest_col; | |||
2872 | d->terminal_delayed_wrap = 0; | |||
2873 | ||||
2874 | if (dist > 0) | |||
2875 | return lineeditor_output_cap1 (d, LINEEDITOR_CAP_CUF6, dist, 1); | |||
2876 | else | |||
2877 | return lineeditor_output_cap1 (d, LINEEDITOR_CAP_CUB7, -dist, 1); | |||
2878 | } | |||
2879 | ||||
2880 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2881 | ||||
2882 | #endif | |||
2883 | } | |||
2884 | ||||
2885 | ||||
2886 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_op_move_row | |||
2887 | ___P((___device_tty *self,(___device_tty *self, int dist) | |||
2888 | int dist),(___device_tty *self, int dist) | |||
2889 | (self,(___device_tty *self, int dist) | |||
2890 | dist)(___device_tty *self, int dist) | |||
2891 | ___device_tty *self;(___device_tty *self, int dist) | |||
2892 | int dist;)(___device_tty *self, int dist) | |||
2893 | { | |||
2894 | /* | |||
2895 | * This routine performs a relative cursor positioning operation | |||
2896 | * that changes the row of the cursor. It also tracks the movement | |||
2897 | * of the emulated terminal's cursor. | |||
2898 | */ | |||
2899 | ||||
2900 | ___device_tty *d = self; | |||
2901 | int row = d->terminal_row; | |||
2902 | int dest_row = row + dist; | |||
2903 | ||||
2904 | if (dest_row < 0) | |||
2905 | dest_row = 0; | |||
2906 | else if (dest_row >= d->terminal_nb_rows) | |||
2907 | dest_row = d->terminal_nb_rows - 1; | |||
2908 | ||||
2909 | #ifdef USE_WIN32 | |||
2910 | ||||
2911 | return lineeditor_output_terminal_op_move_abs | |||
2912 | (d, | |||
2913 | d->terminal_col, | |||
2914 | dest_row); | |||
2915 | ||||
2916 | #else | |||
2917 | ||||
2918 | dist = dest_row - row; | |||
2919 | ||||
2920 | if (dist != 0) | |||
2921 | { | |||
2922 | d->terminal_row = dest_row; | |||
2923 | d->terminal_cursor = dest_row * d->terminal_nb_cols + d->terminal_col; | |||
2924 | d->terminal_delayed_wrap = 0; | |||
2925 | ||||
2926 | if (dist > 0) | |||
2927 | { | |||
2928 | if ((dist == 1 || lineeditor_cap (d, LINEEDITOR_CAP_CUD5) == NULL((void*)0)) && | |||
2929 | lineeditor_cap (d, LINEEDITOR_CAP_CUD13) != NULL((void*)0)) | |||
2930 | return lineeditor_output_cap0 (d, LINEEDITOR_CAP_CUD13, dist); | |||
2931 | else | |||
2932 | return lineeditor_output_cap1 (d, LINEEDITOR_CAP_CUD5, dist, 1); | |||
2933 | } | |||
2934 | else | |||
2935 | { | |||
2936 | if ((dist == -1 || lineeditor_cap (d, LINEEDITOR_CAP_CUU4) == NULL((void*)0)) && | |||
2937 | lineeditor_cap (d, LINEEDITOR_CAP_CUU12) != NULL((void*)0)) | |||
2938 | return lineeditor_output_cap0 (d, LINEEDITOR_CAP_CUU12, -dist); | |||
2939 | else | |||
2940 | return lineeditor_output_cap1 (d, LINEEDITOR_CAP_CUU4, -dist, 1); | |||
2941 | } | |||
2942 | } | |||
2943 | ||||
2944 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2945 | ||||
2946 | #endif | |||
2947 | } | |||
2948 | ||||
2949 | ||||
2950 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_op_move_abs | |||
2951 | ___P((___device_tty *self,(___device_tty *self, int dest_col, int dest_row) | |||
2952 | int dest_col,(___device_tty *self, int dest_col, int dest_row) | |||
2953 | int dest_row),(___device_tty *self, int dest_col, int dest_row) | |||
2954 | (self,(___device_tty *self, int dest_col, int dest_row) | |||
2955 | dest_col,(___device_tty *self, int dest_col, int dest_row) | |||
2956 | dest_row)(___device_tty *self, int dest_col, int dest_row) | |||
2957 | ___device_tty *self;(___device_tty *self, int dest_col, int dest_row) | |||
2958 | int dest_col;(___device_tty *self, int dest_col, int dest_row) | |||
2959 | int dest_row;)(___device_tty *self, int dest_col, int dest_row) | |||
2960 | { | |||
2961 | /* | |||
2962 | * This routine performs an absolute cursor positioning operation. | |||
2963 | * It also tracks the movement of the emulated terminal's cursor. | |||
2964 | */ | |||
2965 | ||||
2966 | ___device_tty *d = self; | |||
2967 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
2968 | ||||
2969 | #ifdef USE_WIN32 | |||
2970 | ||||
2971 | { | |||
2972 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
2973 | ||||
2974 | if (!GetConsoleScreenBufferInfo (d->hout, &info)) | |||
2975 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
2976 | else | |||
2977 | { | |||
2978 | COORD pos = info.dwCursorPosition; | |||
2979 | ||||
2980 | pos.X += dest_col - d->terminal_col; | |||
2981 | pos.Y += dest_row - d->terminal_row; | |||
2982 | ||||
2983 | d->terminal_col = dest_col; | |||
2984 | d->terminal_row = dest_row; | |||
2985 | d->terminal_cursor = dest_row * d->terminal_nb_cols + dest_col; | |||
2986 | d->terminal_delayed_wrap = 0; | |||
2987 | ||||
2988 | if (!SetConsoleCursorPosition (d->hout, pos)) | |||
2989 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
2990 | } | |||
2991 | } | |||
2992 | ||||
2993 | #else | |||
2994 | ||||
2995 | if (dest_col == 0 && | |||
2996 | dest_row == 0 && | |||
2997 | lineeditor_cap (d, LINEEDITOR_CAP_HOME0) != NULL((void*)0)) | |||
2998 | { | |||
2999 | d->terminal_col = 0; | |||
3000 | d->terminal_row = 0; | |||
3001 | d->terminal_cursor = 0; | |||
3002 | d->terminal_delayed_wrap = 0; | |||
3003 | ||||
3004 | return lineeditor_output_cap0 (d, LINEEDITOR_CAP_HOME0, 1); | |||
3005 | } | |||
3006 | ||||
3007 | if (lineeditor_cap (d, LINEEDITOR_CAP_CUP8) != NULL((void*)0)) | |||
3008 | { | |||
3009 | d->terminal_col = dest_col; | |||
3010 | d->terminal_row = dest_row; | |||
3011 | d->terminal_cursor = dest_row * d->terminal_nb_cols + dest_col; | |||
3012 | d->terminal_delayed_wrap = 0; | |||
3013 | ||||
3014 | return lineeditor_output_cap2 | |||
3015 | (d, | |||
3016 | LINEEDITOR_CAP_CUP8, | |||
3017 | dest_row, | |||
3018 | dest_col, | |||
3019 | 1); | |||
3020 | } | |||
3021 | ||||
3022 | if ((e = lineeditor_output_terminal_op_move_col | |||
3023 | (d, | |||
3024 | dest_col - d->terminal_col)) == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3025 | e = lineeditor_output_terminal_op_move_row | |||
3026 | (d, | |||
3027 | dest_row - d->terminal_row); | |||
3028 | ||||
3029 | #endif | |||
3030 | ||||
3031 | return e; | |||
3032 | } | |||
3033 | ||||
3034 | ||||
3035 | #define TERMINAL_MOVE_ABS1 1 | |||
3036 | #define TERMINAL_MOVE_ROW0 0 | |||
3037 | #define TERMINAL_MOVE_COL-1 -1 | |||
3038 | #define TERMINAL_ERASE_DISP-2 -2 | |||
3039 | #define TERMINAL_ERASE_LINE-3 -3 | |||
3040 | #define TERMINAL_SET_ATTRS-4 -4 | |||
3041 | #define TERMINAL_NOOP-5 -5 | |||
3042 | #define TERMINAL_CTRL-6 -6 | |||
3043 | #define TERMINAL_WINDOW_OP-7 -7 | |||
3044 | ||||
3045 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_op | |||
3046 | ___P((___device_tty *self,(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3047 | int op,(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3048 | int arg,(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3049 | ___U8 *text_arg),(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3050 | (self,(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3051 | op,(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3052 | arg,(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3053 | text_arg)(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3054 | ___device_tty *self;(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3055 | int op;(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3056 | int arg;(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3057 | ___U8 *text_arg;)(___device_tty *self, int op, int arg, unsigned char *text_arg ) | |||
3058 | { | |||
3059 | /* | |||
3060 | * This routine performs an operation of the emulated terminal and | |||
3061 | * tracks the movement of the cursor. | |||
3062 | */ | |||
3063 | ||||
3064 | ___device_tty *d = self; | |||
3065 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
3066 | ||||
3067 | switch (op) | |||
3068 | { | |||
3069 | case TERMINAL_NOOP-5: | |||
3070 | break; | |||
3071 | ||||
3072 | case TERMINAL_CTRL-6 - ___UNICODE_BELL7: | |||
3073 | { | |||
3074 | #ifdef USE_POSIX | |||
3075 | ||||
3076 | { | |||
3077 | ___Cunsigned int c = ___UNICODE_BELL7; | |||
3078 | e = lineeditor_output (d, &c, 1); | |||
3079 | } | |||
3080 | ||||
3081 | #endif | |||
3082 | ||||
3083 | #ifdef USE_WIN32 | |||
3084 | ||||
3085 | if (!MessageBeep (MB_OK)) | |||
3086 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3087 | ||||
3088 | #endif | |||
3089 | ||||
3090 | break; | |||
3091 | } | |||
3092 | ||||
3093 | case TERMINAL_CTRL-6 - ___UNICODE_BACKSPACE8: | |||
3094 | { | |||
3095 | if (d->terminal_col > 0) | |||
3096 | d->terminal_col--; | |||
3097 | else if (d->terminal_row > 0 && d->has_auto_left_margin) | |||
3098 | { | |||
3099 | d->terminal_row--; | |||
3100 | d->terminal_col = d->terminal_nb_cols - 1; | |||
3101 | } | |||
3102 | ||||
3103 | d->terminal_cursor = d->terminal_row * d->terminal_nb_cols + | |||
3104 | d->terminal_col; | |||
3105 | ||||
3106 | d->terminal_delayed_wrap = 0; | |||
3107 | ||||
3108 | #ifdef USE_POSIX | |||
3109 | ||||
3110 | { | |||
3111 | ___Cunsigned int c = ___UNICODE_BACKSPACE8; | |||
3112 | e = lineeditor_output (d, &c, 1); | |||
3113 | } | |||
3114 | ||||
3115 | #endif | |||
3116 | ||||
3117 | #ifdef USE_WIN32 | |||
3118 | ||||
3119 | { | |||
3120 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
3121 | ||||
3122 | if (!GetConsoleScreenBufferInfo (d->hout, &info)) | |||
3123 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3124 | else | |||
3125 | { | |||
3126 | COORD pos = info.dwCursorPosition; | |||
3127 | ||||
3128 | if (pos.X > 0) | |||
3129 | pos.X--; | |||
3130 | else if (pos.Y > info.srWindow.Top && d->has_auto_left_margin) | |||
3131 | { | |||
3132 | pos.X = info.dwSize.X - 1; | |||
3133 | pos.Y--; | |||
3134 | } | |||
3135 | ||||
3136 | if (!SetConsoleCursorPosition (d->hout, pos)) | |||
3137 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3138 | } | |||
3139 | } | |||
3140 | ||||
3141 | #endif | |||
3142 | ||||
3143 | break; | |||
3144 | } | |||
3145 | ||||
3146 | case TERMINAL_CTRL-6 - ___UNICODE_TAB9: | |||
3147 | { | |||
3148 | e = lineeditor_output_terminal_op_move_col | |||
3149 | (d, | |||
3150 | 8 - d->terminal_col % 8); | |||
3151 | break; | |||
3152 | } | |||
3153 | ||||
3154 | case TERMINAL_CTRL-6 - ___UNICODE_LINEFEED10: | |||
3155 | { | |||
3156 | if (d->terminal_row < d->terminal_nb_rows-1) | |||
3157 | d->terminal_row++; | |||
3158 | else | |||
3159 | d->current.line_start -= d->terminal_nb_cols; | |||
3160 | ||||
3161 | if (d->linefeed_moves_to_left_margin || !d->output_raw) | |||
3162 | d->terminal_col = 0; | |||
3163 | ||||
3164 | d->terminal_cursor = d->terminal_row * d->terminal_nb_cols + | |||
3165 | d->terminal_col; | |||
3166 | ||||
3167 | d->terminal_delayed_wrap = 0; | |||
3168 | ||||
3169 | #ifdef USE_POSIX | |||
3170 | ||||
3171 | { | |||
3172 | ___Cunsigned int c = ___UNICODE_LINEFEED10; | |||
3173 | e = lineeditor_output (d, &c, 1); | |||
3174 | } | |||
3175 | ||||
3176 | #endif | |||
3177 | ||||
3178 | #ifdef USE_WIN32 | |||
3179 | ||||
3180 | { | |||
3181 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
3182 | ||||
3183 | if (!GetConsoleScreenBufferInfo (d->hout, &info)) | |||
3184 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3185 | else | |||
3186 | { | |||
3187 | COORD pos = info.dwCursorPosition; | |||
3188 | ||||
3189 | if (pos.Y >= info.dwSize.Y - 1) | |||
3190 | { | |||
3191 | SMALL_RECT rect; | |||
3192 | CHAR_INFO fill; | |||
3193 | COORD dest; | |||
3194 | ||||
3195 | rect.Top = 0; | |||
3196 | rect.Bottom = info.dwSize.Y - 1; | |||
3197 | rect.Left = 0; | |||
3198 | rect.Right = info.dwSize.X - 1; | |||
3199 | ||||
3200 | dest.X = 0; | |||
3201 | dest.Y = -1; | |||
3202 | ||||
3203 | fill.Attributes = info.wAttributes; | |||
3204 | TTY_CHAR_SELECT(fill.Char.AsciiChar = ' ',fill.Char.AsciiChar = ' ' | |||
3205 | fill.Char.UnicodeChar = ' ')fill.Char.AsciiChar = ' '; | |||
3206 | ||||
3207 | if (!ScrollConsoleScreenBuffer (d->hout, | |||
3208 | &rect, | |||
3209 | &rect, | |||
3210 | dest, | |||
3211 | &fill)) | |||
3212 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3213 | ||||
3214 | pos.Y = info.dwSize.Y - 1; | |||
3215 | } | |||
3216 | else | |||
3217 | pos.Y++; | |||
3218 | ||||
3219 | if (e == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3220 | { | |||
3221 | if (d->linefeed_moves_to_left_margin || !d->output_raw) | |||
3222 | pos.X = 0; | |||
3223 | ||||
3224 | if (!SetConsoleCursorPosition (d->hout, pos)) | |||
3225 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3226 | } | |||
3227 | } | |||
3228 | } | |||
3229 | ||||
3230 | #endif | |||
3231 | ||||
3232 | break; | |||
3233 | } | |||
3234 | ||||
3235 | case TERMINAL_CTRL-6 - ___UNICODE_RETURN13: | |||
3236 | { | |||
3237 | d->terminal_col = 0; | |||
3238 | d->terminal_cursor = d->terminal_row * d->terminal_nb_cols; | |||
3239 | d->terminal_delayed_wrap = 0; | |||
3240 | ||||
3241 | #ifdef USE_POSIX | |||
3242 | ||||
3243 | { | |||
3244 | ___Cunsigned int c = ___UNICODE_RETURN13; | |||
3245 | e = lineeditor_output (d, &c, 1); | |||
3246 | } | |||
3247 | ||||
3248 | #endif | |||
3249 | ||||
3250 | #ifdef USE_WIN32 | |||
3251 | ||||
3252 | { | |||
3253 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
3254 | ||||
3255 | if (!GetConsoleScreenBufferInfo (d->hout, &info)) | |||
3256 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3257 | else | |||
3258 | { | |||
3259 | COORD pos = info.dwCursorPosition; | |||
3260 | ||||
3261 | pos.X = 0; | |||
3262 | ||||
3263 | if (!SetConsoleCursorPosition (d->hout, pos)) | |||
3264 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3265 | } | |||
3266 | } | |||
3267 | ||||
3268 | #endif | |||
3269 | ||||
3270 | break; | |||
3271 | } | |||
3272 | ||||
3273 | case TERMINAL_SET_ATTRS-4: | |||
3274 | { | |||
3275 | #ifdef USE_POSIX | |||
3276 | ||||
3277 | e = lineeditor_output_set_attrs (d, arg); | |||
3278 | ||||
3279 | #endif | |||
3280 | ||||
3281 | #ifdef USE_WIN32 | |||
3282 | ||||
3283 | { | |||
3284 | int style = GET_STYLE(arg)(((arg)>>8)&3); | |||
3285 | int fg = GET_FOREGROUND_COLOR(arg)((arg)&15); | |||
3286 | int bg = GET_BACKGROUND_COLOR(arg)(((arg)>>4)&15); | |||
3287 | WORD attr = 0; | |||
3288 | ||||
3289 | if (fg == DEFAULT_TEXT_COLOR8) | |||
3290 | fg = NORMAL_FOREGROUND0; | |||
3291 | ||||
3292 | if (bg == DEFAULT_TEXT_COLOR8) | |||
3293 | bg = NORMAL_BACKGROUND7; | |||
3294 | ||||
3295 | if (style & TEXT_STYLE_BOLD1) | |||
3296 | attr |= FOREGROUND_INTENSITY; | |||
3297 | ||||
3298 | if (style & TEXT_STYLE_UNDERLINE2) | |||
3299 | attr |= BACKGROUND_INTENSITY; | |||
3300 | ||||
3301 | if (style & TEXT_STYLE_REVERSE4) | |||
3302 | { | |||
3303 | int temp = fg; | |||
3304 | fg = bg; | |||
3305 | bg = temp; | |||
3306 | } | |||
3307 | ||||
3308 | if (fg & 4) attr |= FOREGROUND_BLUE; | |||
3309 | if (fg & 2) attr |= FOREGROUND_GREEN; | |||
3310 | if (fg & 1) attr |= FOREGROUND_RED; | |||
3311 | if (bg & 4) attr |= BACKGROUND_BLUE; | |||
3312 | if (bg & 2) attr |= BACKGROUND_GREEN; | |||
3313 | if (bg & 1) attr |= BACKGROUND_RED; | |||
3314 | ||||
3315 | if (!SetConsoleTextAttribute (d->hout, attr)) | |||
3316 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3317 | } | |||
3318 | ||||
3319 | #endif | |||
3320 | ||||
3321 | break; | |||
3322 | } | |||
3323 | ||||
3324 | #ifdef USE_WIN32 | |||
3325 | ||||
3326 | case TERMINAL_ERASE_DISP-2: | |||
3327 | case TERMINAL_ERASE_LINE-3: | |||
3328 | { | |||
3329 | if (arg <= 2) /* argument valid? */ | |||
3330 | { | |||
3331 | COORD pos; | |||
3332 | CONSOLE_SCREEN_BUFFER_INFO info; | |||
3333 | DWORD n; | |||
3334 | DWORD written; | |||
3335 | ||||
3336 | if (!GetConsoleScreenBufferInfo (d->hout, &info)) | |||
3337 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3338 | ||||
3339 | if (d->terminal_col == 0 && | |||
3340 | d->terminal_row == 0) | |||
3341 | { | |||
3342 | pos.X = 0; | |||
3343 | pos.Y = 0; | |||
3344 | ||||
3345 | if (!SetConsoleCursorPosition (d->hout, pos)) | |||
3346 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3347 | } | |||
3348 | else | |||
3349 | pos = info.dwCursorPosition; | |||
3350 | ||||
3351 | if (arg == 0) | |||
3352 | n = info.dwSize.X - pos.X; | |||
3353 | else | |||
3354 | { | |||
3355 | if (arg == 1) | |||
3356 | n = pos.X; | |||
3357 | else | |||
3358 | n = info.dwSize.X; | |||
3359 | pos.X = 0; | |||
3360 | } | |||
3361 | ||||
3362 | if (op == TERMINAL_ERASE_DISP-2) | |||
3363 | { | |||
3364 | if (arg == 0) | |||
3365 | n += info.dwSize.X * (info.dwSize.Y - pos.Y - 1); | |||
3366 | else | |||
3367 | { | |||
3368 | if (arg == 1) | |||
3369 | n += info.dwSize.X * pos.Y; | |||
3370 | else | |||
3371 | n = info.dwSize.X * info.dwSize.Y; | |||
3372 | pos.Y = 0; | |||
3373 | } | |||
3374 | } | |||
3375 | ||||
3376 | if (!FillConsoleOutputAttribute | |||
3377 | (d->hout, | |||
3378 | info.wAttributes, | |||
3379 | n, | |||
3380 | pos, | |||
3381 | &written) || | |||
3382 | !FillConsoleOutputCharacter | |||
3383 | (d->hout, | |||
3384 | ' ', | |||
3385 | n, | |||
3386 | pos, | |||
3387 | &written)) | |||
3388 | e = err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
3389 | } | |||
3390 | ||||
3391 | break; | |||
3392 | } | |||
3393 | ||||
3394 | case TERMINAL_WINDOW_OP-7: | |||
3395 | { | |||
3396 | int window_op = arg & ((1<<8)-1); | |||
3397 | int arg1 = (arg >> 8) & ((1<<12)-1); | |||
3398 | int arg2 = (arg >> 20) & ((1<<12)-1); | |||
3399 | HWND cons_wind = GetConsoleWindow (); | |||
3400 | ||||
3401 | if (cons_wind != NULL((void*)0)) | |||
3402 | { | |||
3403 | if (text_arg != NULL((void*)0)) | |||
3404 | { | |||
3405 | SetWindowTextA (cons_wind, | |||
3406 | ___CAST(LPCSTR,text_arg)((LPCSTR)(text_arg))); /* ignore error */ | |||
3407 | } | |||
3408 | else | |||
3409 | { | |||
3410 | switch (window_op) | |||
3411 | { | |||
3412 | case 1: /* De-iconify window */ | |||
3413 | case 2: /* Iconify window */ | |||
3414 | ShowWindow (cons_wind, | |||
3415 | (window_op == 1) ? SW_RESTORE : SW_MINIMIZE); | |||
3416 | break; | |||
3417 | ||||
3418 | case 3: /* Move window to [arg1, arg2] */ | |||
3419 | SetWindowPos (cons_wind, | |||
3420 | cons_wind, | |||
3421 | arg1, | |||
3422 | arg2, | |||
3423 | 0, | |||
3424 | 0, | |||
3425 | SWP_NOZORDER | SWP_NOSIZE); | |||
3426 | break; | |||
3427 | ||||
3428 | case 4: /* Resize window to height=arg1 and width=arg2 in pixels */ | |||
3429 | SetWindowPos (cons_wind, | |||
3430 | cons_wind, | |||
3431 | 0, | |||
3432 | 0, | |||
3433 | arg2, | |||
3434 | arg1, | |||
3435 | SWP_NOZORDER | SWP_NOMOVE); | |||
3436 | break; | |||
3437 | ||||
3438 | case 5: /* Raise the window to the front of the stacking order */ | |||
3439 | case 6: /* Lower the window to the bottom of the stacking order */ | |||
3440 | SetWindowPos (cons_wind, | |||
3441 | (window_op == 5) ? HWND_TOP : HWND_BOTTOM, | |||
3442 | 0, | |||
3443 | 0, | |||
3444 | 0, | |||
3445 | 0, | |||
3446 | SWP_NOSIZE | SWP_NOMOVE); | |||
3447 | break; | |||
3448 | ||||
3449 | case 7: /* Refresh the window */ | |||
3450 | break; | |||
3451 | ||||
3452 | case 8: /* Resize window to height=arg1 and width=arg2 in chars */ | |||
3453 | break; | |||
3454 | ||||
3455 | case 9: /* Maximize or un-maximize window (arg1=0 or arg1=1) */ | |||
3456 | ShowWindow (cons_wind, | |||
3457 | (arg1 == 0) ? SW_MAXIMIZE : SW_RESTORE); | |||
3458 | break; | |||
3459 | } | |||
3460 | } | |||
3461 | } | |||
3462 | ||||
3463 | break; | |||
3464 | } | |||
3465 | ||||
3466 | #else | |||
3467 | ||||
3468 | case TERMINAL_ERASE_DISP-2: | |||
3469 | { | |||
3470 | switch (arg) | |||
3471 | { | |||
3472 | case 1: /* erase from beginning of screen */ | |||
3473 | break; | |||
3474 | case 2: /* erase all screen */ | |||
3475 | if (d->terminal_col != 0 || d->terminal_row != 0) | |||
3476 | break; | |||
3477 | case 0: /* erase to end of screen */ | |||
3478 | e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_ED15, 1); | |||
3479 | break; | |||
3480 | } | |||
3481 | break; | |||
3482 | } | |||
3483 | ||||
3484 | case TERMINAL_ERASE_LINE-3: | |||
3485 | { | |||
3486 | switch (arg) | |||
3487 | { | |||
3488 | case 1: /* erase from beginning of line */ | |||
3489 | e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_EL117, 1); | |||
3490 | break; | |||
3491 | case 2: /* erase all line */ | |||
3492 | if (d->terminal_col != 0) | |||
3493 | break; | |||
3494 | case 0: /* erase to end of line */ | |||
3495 | e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_EL16, 1); | |||
3496 | break; | |||
3497 | } | |||
3498 | break; | |||
3499 | } | |||
3500 | ||||
3501 | case TERMINAL_WINDOW_OP-7: | |||
3502 | { | |||
3503 | int window_op = arg & ((1<<8)-1); | |||
3504 | int arg1 = (arg >> 8) & ((1<<12)-1); | |||
3505 | int arg2 = (arg >> 20) & ((1<<12)-1); | |||
3506 | ||||
3507 | if (text_arg != NULL((void*)0)) | |||
3508 | { | |||
3509 | ___Cunsigned int c; | |||
3510 | ||||
3511 | e = lineeditor_output_cap1 | |||
3512 | (d, | |||
3513 | LINEEDITOR_CAP_WINDOW_OP321, | |||
3514 | window_op, | |||
3515 | 1); | |||
3516 | ||||
3517 | while (e == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
3518 | *text_arg != ___UNICODE_NUL0) | |||
3519 | { | |||
3520 | c = *text_arg++; | |||
3521 | e = lineeditor_output (d, &c, 1); | |||
3522 | } | |||
3523 | ||||
3524 | if (e == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3525 | { | |||
3526 | c = ___UNICODE_BELL7; | |||
3527 | e = lineeditor_output (d, &c, 1); | |||
3528 | } | |||
3529 | } | |||
3530 | else | |||
3531 | { | |||
3532 | switch (window_op) | |||
3533 | { | |||
3534 | case 1: /* De-iconify window */ | |||
3535 | case 2: /* Iconify window */ | |||
3536 | case 5: /* Raise the window to the front of the stacking order */ | |||
3537 | case 6: /* Lower the window to the bottom of the stacking order */ | |||
3538 | case 7: /* Refresh the window */ | |||
3539 | e = lineeditor_output_cap1 | |||
3540 | (d, | |||
3541 | LINEEDITOR_CAP_WINDOW_OP018, | |||
3542 | window_op, | |||
3543 | 1); | |||
3544 | break; | |||
3545 | ||||
3546 | case 9: /* Maximize or un-maximize window (arg1=0 or arg1=1) */ | |||
3547 | e = lineeditor_output_cap2 | |||
3548 | (d, | |||
3549 | LINEEDITOR_CAP_WINDOW_OP119, | |||
3550 | window_op, | |||
3551 | arg1, | |||
3552 | 1); | |||
3553 | break; | |||
3554 | ||||
3555 | case 3: /* Move window to [arg1, arg2] */ | |||
3556 | case 4: /* Resize window to height=arg1 and width=arg2 in pixels */ | |||
3557 | case 8: /* Resize window to height=arg1 and width=arg2 in chars */ | |||
3558 | e = lineeditor_output_cap3 | |||
3559 | (d, | |||
3560 | LINEEDITOR_CAP_WINDOW_OP220, | |||
3561 | window_op, | |||
3562 | arg1, | |||
3563 | arg2, | |||
3564 | 1); | |||
3565 | break; | |||
3566 | } | |||
3567 | } | |||
3568 | ||||
3569 | break; | |||
3570 | } | |||
3571 | ||||
3572 | #endif | |||
3573 | ||||
3574 | case TERMINAL_MOVE_COL-1: | |||
3575 | { | |||
3576 | e = lineeditor_output_terminal_op_move_col (d, arg); | |||
3577 | break; | |||
3578 | } | |||
3579 | ||||
3580 | case TERMINAL_MOVE_ROW0: | |||
3581 | { | |||
3582 | e = lineeditor_output_terminal_op_move_row (d, arg); | |||
3583 | break; | |||
3584 | } | |||
3585 | ||||
3586 | default: | |||
3587 | { | |||
3588 | if (op >= TERMINAL_MOVE_ABS1) | |||
3589 | e = lineeditor_output_terminal_op_move_abs | |||
3590 | (d, | |||
3591 | arg, | |||
3592 | op - TERMINAL_MOVE_ABS1); | |||
3593 | break; | |||
3594 | } | |||
3595 | } | |||
3596 | ||||
3597 | return e; | |||
3598 | } | |||
3599 | ||||
3600 | ||||
3601 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_terminal_emulate | |||
3602 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, int len) | |||
3603 | ___C *buf,(___device_tty *self, unsigned int *buf, int len) | |||
3604 | int len),(___device_tty *self, unsigned int *buf, int len) | |||
3605 | (self,(___device_tty *self, unsigned int *buf, int len) | |||
3606 | buf,(___device_tty *self, unsigned int *buf, int len) | |||
3607 | len)(___device_tty *self, unsigned int *buf, int len) | |||
3608 | ___device_tty *self;(___device_tty *self, unsigned int *buf, int len) | |||
3609 | ___C *buf;(___device_tty *self, unsigned int *buf, int len) | |||
3610 | int len;)(___device_tty *self, unsigned int *buf, int len) | |||
3611 | { | |||
3612 | /* | |||
3613 | * This routine processes a string of characters (possibly | |||
3614 | * containing control characters and escape sequences) that the | |||
3615 | * emulated terminal received. It also tracks the movement of the | |||
3616 | * emulated terminal's cursor. | |||
3617 | */ | |||
3618 | ||||
3619 | ___device_tty *d = self; | |||
3620 | ___SCMOBJlong e; | |||
3621 | int pn; | |||
3622 | ___Cunsigned int c; | |||
3623 | ||||
3624 | #ifdef ___DEBUG_TTY | |||
3625 | ||||
3626 | { | |||
3627 | int i; | |||
3628 | ||||
3629 | ___printf ("lineeditor_output_terminal_emulate len: %d ", len); | |||
3630 | ||||
3631 | ___printf ("\""); | |||
3632 | ||||
3633 | for (i=0; i<len; i++) | |||
3634 | if (buf[i] < 32 || buf[i] >= 127) | |||
3635 | ___printf ("\\x%02x", buf[i]); | |||
3636 | else | |||
3637 | ___printf ("%c", buf[i]); | |||
3638 | ||||
3639 | ___printf ("\"\n"); | |||
3640 | } | |||
3641 | ||||
3642 | #endif | |||
3643 | ||||
3644 | pn = d->terminal_param_num; | |||
3645 | ||||
3646 | while (len > 0) | |||
3647 | { | |||
3648 | ___Cunsigned int c = *buf++; | |||
3649 | ||||
3650 | len--; | |||
3651 | ||||
3652 | if (!d->editing_line) | |||
3653 | { | |||
3654 | /* accumulate prompt */ | |||
3655 | ||||
3656 | int i = d->prompt_length; | |||
3657 | if (i < ___CAST(int,___NBELEMS(d->prompt))((int)((sizeof (d->prompt) / sizeof ((d->prompt)[0]))))) | |||
3658 | { | |||
3659 | d->prompt[i] = c; | |||
3660 | d->prompt_length = i+1; | |||
3661 | } | |||
3662 | } | |||
3663 | ||||
3664 | switch (pn) | |||
3665 | { | |||
3666 | case -2: | |||
3667 | { | |||
3668 | /* outside of an escape sequence */ | |||
3669 | ||||
3670 | if (c >= ___UNICODE_SPACE32) | |||
3671 | { | |||
3672 | int n = 0; | |||
3673 | ||||
3674 | while (n < len && *buf >= ___UNICODE_SPACE32) | |||
3675 | { | |||
3676 | n++; | |||
3677 | buf++; | |||
3678 | } | |||
3679 | ||||
3680 | if (!d->editing_line) | |||
3681 | { | |||
3682 | /* accumulate prompt */ | |||
3683 | ||||
3684 | ___Cunsigned int *p = buf - n; | |||
3685 | int i = d->prompt_length; | |||
3686 | while (i < ___CAST(int,___NBELEMS(d->prompt))((int)((sizeof (d->prompt) / sizeof ((d->prompt)[0])))) && p < buf) | |||
3687 | d->prompt[i++] = *p++; | |||
3688 | d->prompt_length = i; | |||
3689 | } | |||
3690 | ||||
3691 | len -= n; | |||
3692 | n++; | |||
3693 | ||||
3694 | if ((e = lineeditor_output_terminal_plain_chars (d, buf-n, n)) | |||
3695 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3696 | { | |||
3697 | d->terminal_param_num = pn; | |||
3698 | return e; | |||
3699 | } | |||
3700 | } | |||
3701 | else if (c != ___UNICODE_ESCAPE27) /* non ESC control character? */ | |||
3702 | { | |||
3703 | if (c == ___UNICODE_LINEFEED10) | |||
3704 | { | |||
3705 | if (!d->editing_line) | |||
3706 | d->prompt_length = 0; /* reset prompt */ | |||
3707 | ||||
3708 | /******** TODO: should check if cr-lf, etc is needed */ | |||
3709 | ||||
3710 | if ((e = lineeditor_output_terminal_op | |||
3711 | (d, | |||
3712 | TERMINAL_CTRL-6 - c, | |||
3713 | 0, | |||
3714 | NULL((void*)0))) | |||
3715 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3716 | { | |||
3717 | d->terminal_param_num = pn; | |||
3718 | return e; | |||
3719 | } | |||
3720 | } | |||
3721 | else | |||
3722 | { | |||
3723 | if ((e = lineeditor_output_terminal_op | |||
3724 | (d, | |||
3725 | TERMINAL_CTRL-6 - c, | |||
3726 | 0, | |||
3727 | NULL((void*)0))) | |||
3728 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3729 | { | |||
3730 | d->terminal_param_num = pn; | |||
3731 | return e; | |||
3732 | } | |||
3733 | } | |||
3734 | } | |||
3735 | else | |||
3736 | pn = -1; /* start of an escape sequence */ | |||
3737 | ||||
3738 | break; | |||
3739 | } | |||
3740 | ||||
3741 | case -1: | |||
3742 | { | |||
3743 | /* after an ESC */ | |||
3744 | ||||
3745 | if (c == '[') | |||
3746 | { | |||
3747 | d->terminal_op_type = 0; | |||
3748 | pn = 0; | |||
3749 | d->terminal_param[0] = 0; | |||
3750 | } | |||
3751 | else if (c == ']') | |||
3752 | { | |||
3753 | d->terminal_op_type = 1; | |||
3754 | pn = 0; | |||
3755 | d->terminal_param[0] = 0; | |||
3756 | } | |||
3757 | else | |||
3758 | pn = -2; | |||
3759 | ||||
3760 | break; | |||
3761 | } | |||
3762 | ||||
3763 | default: | |||
3764 | { | |||
3765 | /* accumulating parameters after an ESC '[' */ | |||
3766 | ||||
3767 | if (d->terminal_op_type == 1 && pn == 1) | |||
3768 | { | |||
3769 | if (c == ___UNICODE_BELL7) | |||
3770 | { | |||
3771 | pn = -2; | |||
3772 | ||||
3773 | if ((e = lineeditor_output_terminal_op | |||
3774 | (d, | |||
3775 | TERMINAL_WINDOW_OP-7, | |||
3776 | d->terminal_param[0], | |||
3777 | d->terminal_param_text)) | |||
3778 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3779 | { | |||
3780 | d->terminal_param_num = pn; | |||
3781 | return e; | |||
3782 | } | |||
3783 | } | |||
3784 | else | |||
3785 | { | |||
3786 | if (d->terminal_param[1] < | |||
3787 | ___CAST(int,___NBELEMS(d->terminal_param_text))((int)((sizeof (d->terminal_param_text) / sizeof ((d->terminal_param_text )[0]))))-1) | |||
3788 | d->terminal_param_text[d->terminal_param[1]++] = c; | |||
3789 | } | |||
3790 | } | |||
3791 | else if (c >= '0' && c <= '9') | |||
3792 | { | |||
3793 | int x = c - '0'; | |||
3794 | int p = d->terminal_param[pn]; | |||
3795 | if (p < 1000) | |||
3796 | d->terminal_param[pn] = p*10 + x; | |||
3797 | } | |||
3798 | else if (c == ';') | |||
3799 | { | |||
3800 | if (pn < ___CAST(int,___NBELEMS(d->terminal_param))((int)((sizeof (d->terminal_param) / sizeof ((d->terminal_param )[0]))))-1) | |||
3801 | pn++; | |||
3802 | d->terminal_param[pn] = 0; | |||
3803 | } | |||
3804 | else | |||
3805 | { | |||
3806 | int op = TERMINAL_NOOP-5; | |||
3807 | int arg = 0; | |||
3808 | ||||
3809 | if (c == 'A') | |||
3810 | { | |||
3811 | op = TERMINAL_MOVE_ROW0; | |||
3812 | arg = -d->terminal_param[0]; | |||
3813 | if (arg >= 0) arg = -1; | |||
3814 | } | |||
3815 | else if (c == 'B') | |||
3816 | { | |||
3817 | op = TERMINAL_MOVE_ROW0; | |||
3818 | arg = d->terminal_param[0]; | |||
3819 | if (arg <= 0) arg = 1; | |||
3820 | } | |||
3821 | else if (c == 'C') | |||
3822 | { | |||
3823 | op = TERMINAL_MOVE_COL-1; | |||
3824 | arg = d->terminal_param[0]; | |||
3825 | if (arg <= 0) arg = 1; | |||
3826 | } | |||
3827 | else if (c == 'D') | |||
3828 | { | |||
3829 | op = TERMINAL_MOVE_COL-1; | |||
3830 | arg = -d->terminal_param[0]; | |||
3831 | if (arg >= 0) arg = -1; | |||
3832 | } | |||
3833 | else if (c == 'H' || c == 'f') | |||
3834 | { | |||
3835 | op = d->terminal_param[0]; | |||
3836 | if (op <= 0) op = 1; | |||
3837 | op += TERMINAL_MOVE_ABS1 - 1; | |||
3838 | arg = d->terminal_param[1]; | |||
3839 | if (pn < 1 || arg <= 0) arg = 1; | |||
3840 | arg--; | |||
3841 | } | |||
3842 | else if (c == 'J') | |||
3843 | { | |||
3844 | op = TERMINAL_ERASE_DISP-2; | |||
3845 | arg = d->terminal_param[0]; | |||
3846 | if (arg <= 0) arg = 0; | |||
3847 | } | |||
3848 | else if (c == 'K') | |||
3849 | { | |||
3850 | op = TERMINAL_ERASE_LINE-3; | |||
3851 | arg = d->terminal_param[0]; | |||
3852 | if (arg <= 0) arg = 0; | |||
3853 | } | |||
3854 | else if (c == 'm') | |||
3855 | { | |||
3856 | int j; | |||
3857 | int style; | |||
3858 | int fg; | |||
3859 | int bg; | |||
3860 | ||||
3861 | op = TERMINAL_SET_ATTRS-4; | |||
3862 | arg = d->terminal_attrs; | |||
3863 | style = GET_STYLE(arg)(((arg)>>8)&3); | |||
3864 | fg = GET_FOREGROUND_COLOR(arg)((arg)&15); | |||
3865 | bg = GET_BACKGROUND_COLOR(arg)(((arg)>>4)&15); | |||
3866 | ||||
3867 | for (j=0; j<=pn; j++) | |||
3868 | { | |||
3869 | int x = d->terminal_param[j]; | |||
3870 | if (x <= 0) | |||
3871 | { | |||
3872 | style = TEXT_STYLE_NORMAL0; | |||
3873 | fg = DEFAULT_TEXT_COLOR8; | |||
3874 | bg = DEFAULT_TEXT_COLOR8; | |||
3875 | } | |||
3876 | else if (x == 1) | |||
3877 | style |= TEXT_STYLE_BOLD1; | |||
3878 | else if (x == 4) | |||
3879 | style |= TEXT_STYLE_UNDERLINE2; | |||
3880 | else if (x == 7) | |||
3881 | style |= TEXT_STYLE_REVERSE4; | |||
3882 | else if (x >= 30 && x <= 37) | |||
3883 | fg = x-30; | |||
3884 | else if (x >= 40 && x <= 47) | |||
3885 | bg = x-40; | |||
3886 | } | |||
3887 | arg = MAKE_TEXT_ATTRS(style,fg,bg)(((style)<<8)+(fg)+((bg)<<4)); | |||
3888 | } | |||
3889 | else if (c == 't') | |||
3890 | { | |||
3891 | switch (d->terminal_param[0]) | |||
3892 | { | |||
3893 | case 3: | |||
3894 | case 4: | |||
3895 | case 8: | |||
3896 | if (pn == 2 && | |||
3897 | d->terminal_param[1] <= 4095 && | |||
3898 | d->terminal_param[2] <= 4095) | |||
3899 | { | |||
3900 | arg = (d->terminal_param[2] << 20) + | |||
3901 | (d->terminal_param[1] << 8) + | |||
3902 | d->terminal_param[0]; | |||
3903 | op = TERMINAL_WINDOW_OP-7; | |||
3904 | } | |||
3905 | break; | |||
3906 | ||||
3907 | case 9: | |||
3908 | if (pn == 1 && | |||
3909 | d->terminal_param[1] <= 4095) | |||
3910 | { | |||
3911 | arg = (d->terminal_param[1] << 8) + | |||
3912 | d->terminal_param[0]; | |||
3913 | op = TERMINAL_WINDOW_OP-7; | |||
3914 | } | |||
3915 | break; | |||
3916 | ||||
3917 | default: | |||
3918 | if (pn == 0 && | |||
3919 | d->terminal_param[0] >= 1 && | |||
3920 | d->terminal_param[0] <= 9) | |||
3921 | { | |||
3922 | arg = d->terminal_param[0]; | |||
3923 | op = TERMINAL_WINDOW_OP-7; | |||
3924 | } | |||
3925 | break; | |||
3926 | } | |||
3927 | } | |||
3928 | ||||
3929 | pn = -2; | |||
3930 | ||||
3931 | if ((e = lineeditor_output_terminal_op (d, op, arg, NULL((void*)0))) | |||
3932 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3933 | { | |||
3934 | d->terminal_param_num = pn; | |||
3935 | return e; | |||
3936 | } | |||
3937 | } | |||
3938 | ||||
3939 | break; | |||
3940 | } | |||
3941 | } | |||
3942 | } | |||
3943 | ||||
3944 | d->terminal_param_num = pn; | |||
3945 | ||||
3946 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
3947 | } | |||
3948 | ||||
3949 | ||||
3950 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_chars | |||
3951 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3952 | ___C *buf,(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3953 | ___stream_index len,(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3954 | tty_text_attrs attrs),(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3955 | (self,(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3956 | buf,(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3957 | len,(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3958 | attrs)(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3959 | ___device_tty *self;(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3960 | ___C *buf;(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3961 | ___stream_index len;(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3962 | tty_text_attrs attrs;)(___device_tty *self, unsigned int *buf, ___stream_index len, tty_text_attrs attrs) | |||
3963 | { | |||
3964 | /* | |||
3965 | * This routine outputs "len" characters from the buffer "buf" using | |||
3966 | * the text attributes "attrs". | |||
3967 | */ | |||
3968 | ||||
3969 | ___device_tty *d = self; | |||
3970 | ___SCMOBJlong e; | |||
3971 | ||||
3972 | if ((e = lineeditor_output_set_attrs (d, attrs)) | |||
3973 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
3974 | e = lineeditor_output (d, buf, len); | |||
3975 | ||||
3976 | return e; | |||
3977 | } | |||
3978 | ||||
3979 | ||||
3980 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_char_repetition | |||
3981 | ___P((___device_tty *self,(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3982 | ___C c,(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3983 | int rep,(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3984 | tty_text_attrs attrs),(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3985 | (self,(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3986 | c,(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3987 | rep,(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3988 | attrs)(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3989 | ___device_tty *self;(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3990 | ___C c;(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3991 | int rep;(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3992 | tty_text_attrs attrs;)(___device_tty *self, unsigned int c, int rep, tty_text_attrs attrs) | |||
3993 | { | |||
3994 | /* | |||
3995 | * This routine outputs the character "c" a total of "rep" times | |||
3996 | * using the text attributes "attrs". | |||
3997 | */ | |||
3998 | ||||
3999 | #define CHAR_BUFFER_SIZE(80*50) (80*50) | |||
4000 | ||||
4001 | ___device_tty *d = self; | |||
4002 | ___SCMOBJlong e; | |||
4003 | ___Cunsigned int char_buffer[CHAR_BUFFER_SIZE(80*50)]; | |||
4004 | int n; | |||
4005 | ||||
4006 | n = rep; | |||
4007 | if (n > CHAR_BUFFER_SIZE(80*50)) | |||
4008 | n = CHAR_BUFFER_SIZE(80*50); | |||
4009 | ||||
4010 | while (n > 0) | |||
4011 | char_buffer[--n] = c; | |||
4012 | ||||
4013 | while (rep > 0) | |||
4014 | { | |||
4015 | n = rep; | |||
4016 | if (n > CHAR_BUFFER_SIZE(80*50)) | |||
4017 | n = CHAR_BUFFER_SIZE(80*50); | |||
4018 | if ((e = lineeditor_output_chars (d, char_buffer, n, attrs)) | |||
4019 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4020 | return e; | |||
4021 | rep -= n; | |||
4022 | } | |||
4023 | ||||
4024 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4025 | } | |||
4026 | ||||
4027 | ||||
4028 | ___HIDDENstatic tty_text_attrs lineeditor_erase_attrs | |||
4029 | ___P((___device_tty *self),(___device_tty *self) | |||
4030 | (self)(___device_tty *self) | |||
4031 | ___device_tty *self;)(___device_tty *self) | |||
4032 | { | |||
4033 | /* | |||
4034 | * This routine returns the text attributes that should be used to | |||
4035 | * erase portions of the screen. | |||
4036 | */ | |||
4037 | ||||
4038 | ___device_tty *d = self; | |||
4039 | tty_text_attrs output_attrs = d->output_attrs; | |||
4040 | int output_style = GET_STYLE(output_attrs)(((output_attrs)>>8)&3); | |||
4041 | int current_style = GET_STYLE(d->current.attrs)(((d->current.attrs)>>8)&3); | |||
4042 | ||||
4043 | return MAKE_TEXT_ATTRS(output_style & TEXT_STYLE_REVERSE,(((output_style & 4)<<8)+(((output_attrs)&15))+ (((((output_attrs)>>4)&15))<<4)) | |||
4044 | GET_FOREGROUND_COLOR(output_attrs),(((output_style & 4)<<8)+(((output_attrs)&15))+ (((((output_attrs)>>4)&15))<<4)) | |||
4045 | GET_BACKGROUND_COLOR(output_attrs))(((output_style & 4)<<8)+(((output_attrs)&15))+ (((((output_attrs)>>4)&15))<<4)); | |||
4046 | } | |||
4047 | ||||
4048 | ||||
4049 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_current_hist | |||
4050 | ___P((___device_tty *self,(___device_tty *self, int start, int len) | |||
4051 | int start,(___device_tty *self, int start, int len) | |||
4052 | int len),(___device_tty *self, int start, int len) | |||
4053 | (self,(___device_tty *self, int start, int len) | |||
4054 | start,(___device_tty *self, int start, int len) | |||
4055 | len)(___device_tty *self, int start, int len) | |||
4056 | ___device_tty *self;(___device_tty *self, int start, int len) | |||
4057 | int start;(___device_tty *self, int start, int len) | |||
4058 | int len;)(___device_tty *self, int start, int len) | |||
4059 | { | |||
4060 | /* | |||
4061 | * This routine sends to the terminal "len" characters of the line | |||
4062 | * being edited starting at position "start". The line is logically | |||
4063 | * padded with spaces at both ends (so that a negative "start" | |||
4064 | * outputs spaces first and if "start+len" is beyond the end of the | |||
4065 | * line some spaces will be output at the end). | |||
4066 | */ | |||
4067 | ||||
4068 | ___device_tty *d = self; | |||
4069 | ___SCMOBJlong e; | |||
4070 | extensible_string *edited = &d->current.hist->edited; | |||
4071 | int spaces_at_head; | |||
4072 | int chars_from_line; | |||
4073 | ||||
4074 | spaces_at_head = -start; | |||
4075 | ||||
4076 | if (spaces_at_head < 0) | |||
4077 | spaces_at_head = 0; | |||
4078 | else | |||
4079 | { | |||
4080 | if (spaces_at_head > len) | |||
4081 | spaces_at_head = len; | |||
4082 | start += spaces_at_head; | |||
4083 | len -= spaces_at_head; | |||
4084 | } | |||
4085 | ||||
4086 | chars_from_line = edited->length - start; | |||
4087 | ||||
4088 | if (chars_from_line < 0) | |||
4089 | chars_from_line = 0; | |||
4090 | else | |||
4091 | { | |||
4092 | if (chars_from_line > len) | |||
4093 | chars_from_line = len; | |||
4094 | len -= chars_from_line; | |||
4095 | } | |||
4096 | ||||
4097 | if (spaces_at_head > 0) | |||
4098 | if ((e = lineeditor_output_char_repetition | |||
4099 | (d, | |||
4100 | ___UNICODE_SPACE32, | |||
4101 | spaces_at_head, | |||
4102 | lineeditor_erase_attrs (d))) | |||
4103 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4104 | return e; | |||
4105 | ||||
4106 | if (chars_from_line > 0) | |||
4107 | if ((e = lineeditor_output_chars | |||
4108 | (d, | |||
4109 | &edited->buffer[start], | |||
4110 | chars_from_line, | |||
4111 | d->input_attrs)) | |||
4112 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4113 | return e; | |||
4114 | ||||
4115 | if (len > 0) | |||
4116 | if ((e = lineeditor_output_char_repetition | |||
4117 | (d, | |||
4118 | ___UNICODE_SPACE32, | |||
4119 | len, | |||
4120 | lineeditor_erase_attrs (d))) | |||
4121 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4122 | return e; | |||
4123 | ||||
4124 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4125 | } | |||
4126 | ||||
4127 | ||||
4128 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_force_delayed_wrap | |||
4129 | ___P((___device_tty *self),(___device_tty *self) | |||
4130 | (self)(___device_tty *self) | |||
4131 | ___device_tty *self;)(___device_tty *self) | |||
4132 | { | |||
4133 | /* | |||
4134 | * This routine forces the cursor to wrap to the next line if the | |||
4135 | * wrap was delayed. | |||
4136 | */ | |||
4137 | ||||
4138 | ___device_tty *d = self; | |||
4139 | ||||
4140 | if (d->terminal_delayed_wrap) | |||
4141 | return lineeditor_output_current_hist | |||
4142 | (d, | |||
4143 | d->terminal_cursor + 1 - d->current.line_start, | |||
4144 | 1); | |||
4145 | ||||
4146 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4147 | } | |||
4148 | ||||
4149 | ||||
4150 | ___HIDDENstatic ___SCMOBJlong lineeditor_move_cursor_plain | |||
4151 | ___P((___device_tty *self,(___device_tty *self, int dist) | |||
4152 | int dist),(___device_tty *self, int dist) | |||
4153 | (self,(___device_tty *self, int dist) | |||
4154 | dist)(___device_tty *self, int dist) | |||
4155 | ___device_tty *self;(___device_tty *self, int dist) | |||
4156 | int dist;)(___device_tty *self, int dist) | |||
4157 | { | |||
4158 | /* | |||
4159 | * This routine sends the appropriate commands to the terminal to | |||
4160 | * move the cursor "dist" positions forward/backward by writing | |||
4161 | * plain characters or backspace characters. We assume that the | |||
4162 | * terminal has auto left/right margins if the cursor needs to | |||
4163 | * change row. | |||
4164 | */ | |||
4165 | ||||
4166 | ___device_tty *d = self; | |||
4167 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4168 | ||||
4169 | if (dist != 0) | |||
4170 | { | |||
4171 | if (dist < 0) | |||
4172 | e = lineeditor_output_char_repetition | |||
4173 | (d, | |||
4174 | ___UNICODE_BACKSPACE8, | |||
4175 | -dist, | |||
4176 | d->current.attrs); | |||
4177 | else | |||
4178 | { | |||
4179 | ___BOOLint need_backspace = ((d->terminal_cursor + dist | |||
4180 | % d->terminal_nb_cols == 0) | |||
4181 | && d->has_eat_newline_glitch); | |||
4182 | ||||
4183 | if ((e = lineeditor_output_current_hist | |||
4184 | (d, | |||
4185 | d->terminal_cursor + d->terminal_delayed_wrap | |||
4186 | - d->current.line_start, | |||
4187 | dist - d->terminal_delayed_wrap + need_backspace)) | |||
4188 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4189 | { | |||
4190 | if (need_backspace) | |||
4191 | e = lineeditor_output_char_repetition | |||
4192 | (d, | |||
4193 | ___UNICODE_BACKSPACE8, | |||
4194 | 1, | |||
4195 | d->current.attrs); | |||
4196 | } | |||
4197 | } | |||
4198 | } | |||
4199 | ||||
4200 | return e; | |||
4201 | } | |||
4202 | ||||
4203 | ||||
4204 | ___HIDDENstatic ___SCMOBJlong lineeditor_move_cursor | |||
4205 | ___P((___device_tty *self,(___device_tty *self, int screen_pos) | |||
4206 | int screen_pos),(___device_tty *self, int screen_pos) | |||
4207 | (self,(___device_tty *self, int screen_pos) | |||
4208 | screen_pos)(___device_tty *self, int screen_pos) | |||
4209 | ___device_tty *self;(___device_tty *self, int screen_pos) | |||
4210 | int screen_pos;)(___device_tty *self, int screen_pos) | |||
4211 | { | |||
4212 | /* | |||
4213 | * This routine sends the appropriate commands to the terminal to | |||
4214 | * move the cursor to position "screen_pos". | |||
4215 | */ | |||
4216 | ||||
4217 | ___device_tty *d = self; | |||
4218 | ___SCMOBJlong e; | |||
4219 | int cursor = d->terminal_cursor; | |||
4220 | ||||
4221 | #ifdef USE_CURSES | |||
4222 | ||||
4223 | int col = screen_pos % d->terminal_nb_cols; | |||
4224 | int col_dist = col - d->terminal_col; | |||
4225 | int row_dist = screen_pos / d->terminal_nb_cols - d->terminal_row; | |||
4226 | ||||
4227 | if (screen_pos <= cursor) | |||
4228 | { | |||
4229 | /* | |||
4230 | * Check if the cursor can be moved backward by writing no more | |||
4231 | * than 4 backspace characters (if on the same row or column) or | |||
4232 | * 8 backspace characters (otherwise). This is probably no more | |||
4233 | * than is required by cursor movement commands. | |||
4234 | */ | |||
4235 | ||||
4236 | if ((row_dist == 0 || d->has_auto_left_margin) && | |||
4237 | cursor - screen_pos <= ((row_dist == 0 || col_dist == 0) ? 4 : 8)) | |||
4238 | return lineeditor_move_cursor_plain (self, screen_pos - cursor); | |||
4239 | } | |||
4240 | else | |||
4241 | { | |||
4242 | /* | |||
4243 | * Check if the cursor can be moved forward by writing no more | |||
4244 | * than 4 plain characters (if on the same row or column) or 8 | |||
4245 | * plain characters (otherwise). This is probably no more than | |||
4246 | * is required by cursor movement commands. | |||
4247 | */ | |||
4248 | ||||
4249 | if ((row_dist == 0 || d->has_auto_right_margin) && | |||
4250 | screen_pos - (cursor + d->terminal_delayed_wrap) | |||
4251 | + ((col == 0 && d->has_eat_newline_glitch) ? 2 : 0) | |||
4252 | <= ((row_dist == 0 || col_dist == 0) ? 4 : 8)) | |||
4253 | return lineeditor_move_cursor_plain (self, screen_pos - cursor); | |||
4254 | } | |||
4255 | ||||
4256 | /* | |||
4257 | * Move the cursor to the target column. | |||
4258 | */ | |||
4259 | ||||
4260 | if ((col_dist >= -4) && (col_dist <= 4)) | |||
4261 | { | |||
4262 | /* Use plain characters if not too far. */ | |||
4263 | ||||
4264 | if ((e = lineeditor_move_cursor_plain (self, col_dist)) | |||
4265 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4266 | return e; | |||
4267 | ||||
4268 | cursor += col_dist; | |||
4269 | col_dist = 0; | |||
4270 | } | |||
4271 | else | |||
4272 | { | |||
4273 | /* Use cursor commands if the terminal supports this. */ | |||
4274 | ||||
4275 | if (lineeditor_cap (d, | |||
4276 | (col_dist > 0) | |||
4277 | ? LINEEDITOR_CAP_CUF6 | |||
4278 | : LINEEDITOR_CAP_CUB7) | |||
4279 | != NULL((void*)0)) | |||
4280 | { | |||
4281 | if ((e = lineeditor_output_cap1 | |||
4282 | (d, | |||
4283 | (col_dist > 0) ? LINEEDITOR_CAP_CUF6 : LINEEDITOR_CAP_CUB7, | |||
4284 | (col_dist > 0) ? col_dist : -col_dist, | |||
4285 | 1)) | |||
4286 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4287 | return e; | |||
4288 | ||||
4289 | cursor += col_dist; | |||
4290 | col_dist = 0; | |||
4291 | } | |||
4292 | } | |||
4293 | ||||
4294 | /* | |||
4295 | * Move the cursor to the target row using cursor movement commands, | |||
4296 | * if the terminal supports this. | |||
4297 | */ | |||
4298 | ||||
4299 | if (row_dist != 0 && | |||
4300 | ((row_dist > 0) | |||
4301 | ? (lineeditor_cap (d, LINEEDITOR_CAP_CUD5) != NULL((void*)0) || | |||
4302 | lineeditor_cap (d, LINEEDITOR_CAP_CUD13) != NULL((void*)0)) | |||
4303 | : (lineeditor_cap (d, LINEEDITOR_CAP_CUU4) != NULL((void*)0) || | |||
4304 | lineeditor_cap (d, LINEEDITOR_CAP_CUU12) != NULL((void*)0)))) | |||
4305 | { | |||
4306 | if ((row_dist > 0) | |||
4307 | ? (lineeditor_cap (d, LINEEDITOR_CAP_CUD5) == NULL((void*)0) || | |||
4308 | (lineeditor_cap (d, LINEEDITOR_CAP_CUD13) != NULL((void*)0) && | |||
4309 | row_dist == 1)) | |||
4310 | : (lineeditor_cap (d, LINEEDITOR_CAP_CUU4) == NULL((void*)0) || | |||
4311 | (lineeditor_cap (d, LINEEDITOR_CAP_CUU12) != NULL((void*)0) && | |||
4312 | row_dist == -1))) | |||
4313 | e = lineeditor_output_cap0 | |||
4314 | (d, | |||
4315 | (row_dist > 0) ? LINEEDITOR_CAP_CUD13 : LINEEDITOR_CAP_CUU12, | |||
4316 | (row_dist > 0) ? row_dist : -row_dist); | |||
4317 | else | |||
4318 | e = lineeditor_output_cap1 | |||
4319 | (d, | |||
4320 | (row_dist > 0) ? LINEEDITOR_CAP_CUD5 : LINEEDITOR_CAP_CUU4, | |||
4321 | (row_dist > 0) ? row_dist : -row_dist, | |||
4322 | 1); | |||
4323 | ||||
4324 | if (e != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4325 | return e; | |||
4326 | ||||
4327 | /* Cursor commands to change row were successful. */ | |||
4328 | ||||
4329 | cursor += row_dist * d->terminal_nb_cols; | |||
4330 | } | |||
4331 | ||||
4332 | #endif | |||
4333 | ||||
4334 | /* | |||
4335 | * If the cursor is still not at the target position, move the | |||
4336 | * cursor by writing plain characters or backspace characters. | |||
4337 | */ | |||
4338 | ||||
4339 | return lineeditor_move_cursor_plain (self, screen_pos - cursor); | |||
4340 | } | |||
4341 | ||||
4342 | ||||
4343 | ___HIDDENstatic ___SCMOBJlong lineeditor_left_margin_of_next_row | |||
4344 | ___P((___device_tty *self),(___device_tty *self) | |||
4345 | (self)(___device_tty *self) | |||
4346 | ___device_tty *self;)(___device_tty *self) | |||
4347 | { | |||
4348 | ___device_tty *d = self; | |||
4349 | ___SCMOBJlong e; | |||
4350 | ||||
4351 | if (!(d->linefeed_moves_to_left_margin || !d->output_raw)) | |||
4352 | if ((e = lineeditor_output_char_repetition | |||
4353 | (d, | |||
4354 | ___UNICODE_RETURN13, | |||
4355 | 1, | |||
4356 | d->output_attrs)) | |||
4357 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4358 | return e; | |||
4359 | ||||
4360 | return lineeditor_output_char_repetition | |||
4361 | (d, | |||
4362 | ___UNICODE_LINEFEED10, | |||
4363 | 1, | |||
4364 | d->output_attrs); | |||
4365 | } | |||
4366 | ||||
4367 | ||||
4368 | ___HIDDENstatic ___SCMOBJlong lineeditor_prepare_to_write_at | |||
4369 | ___P((___device_tty *self,(___device_tty *self, int screen_pos) | |||
4370 | int screen_pos),(___device_tty *self, int screen_pos) | |||
4371 | (self,(___device_tty *self, int screen_pos) | |||
4372 | screen_pos)(___device_tty *self, int screen_pos) | |||
4373 | ___device_tty *self;(___device_tty *self, int screen_pos) | |||
4374 | int screen_pos;)(___device_tty *self, int screen_pos) | |||
4375 | { | |||
4376 | /* | |||
4377 | * This routine sends commands to the terminal such that the next | |||
4378 | * character sent to the terminal will show up at screen position | |||
4379 | * "screen_pos". The position can be equal to the size of the | |||
4380 | * screen, in which case either the screen is scrolled right away or | |||
4381 | * the next character sent to the terminal will cause the screen to | |||
4382 | * scroll. | |||
4383 | */ | |||
4384 | ||||
4385 | ___device_tty *d = self; | |||
4386 | ___SCMOBJlong e; | |||
4387 | int screen_size = d->terminal_size; | |||
4388 | int cursor = d->terminal_cursor; | |||
4389 | ||||
4390 | if (screen_pos > screen_size) | |||
4391 | screen_pos = screen_size; | |||
4392 | ||||
4393 | if (cursor + d->terminal_delayed_wrap == screen_pos) | |||
4394 | e = ___FIX(___NO_ERR)(((long)(0))<<2); /* next character will be at the right place */ | |||
4395 | else if (screen_pos == screen_size) | |||
4396 | { | |||
4397 | if ((e = lineeditor_move_cursor (d, screen_pos-1)) | |||
4398 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4399 | e = lineeditor_output_current_hist | |||
4400 | (d, | |||
4401 | screen_pos - 1 - d->current.line_start, | |||
4402 | 1); | |||
4403 | } | |||
4404 | else | |||
4405 | { | |||
4406 | if ((e = lineeditor_move_cursor (d, screen_pos)) | |||
4407 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4408 | { | |||
4409 | if (d->terminal_delayed_wrap) | |||
4410 | { | |||
4411 | /* | |||
4412 | * Output a backspace and a character. Note that this | |||
4413 | * assumes the screen is at least 2 columns wide. | |||
4414 | */ | |||
4415 | ||||
4416 | if ((e = lineeditor_output_char_repetition | |||
4417 | (d, | |||
4418 | ___UNICODE_BACKSPACE8, | |||
4419 | 1, | |||
4420 | d->current.attrs)) | |||
4421 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4422 | e = lineeditor_output_current_hist | |||
4423 | (d, | |||
4424 | screen_pos - 1 - d->current.line_start, | |||
4425 | 1); | |||
4426 | } | |||
4427 | } | |||
4428 | } | |||
4429 | ||||
4430 | return e; | |||
4431 | } | |||
4432 | ||||
4433 | ||||
4434 | ___HIDDENstatic ___SCMOBJlong lineeditor_newline | |||
4435 | ___P((___device_tty *self),(___device_tty *self) | |||
4436 | (self)(___device_tty *self) | |||
4437 | ___device_tty *self;)(___device_tty *self) | |||
4438 | { | |||
4439 | /* | |||
4440 | * This routine moves the cursor to the left margin of the row | |||
4441 | * following the last visible part of the line being edited. | |||
4442 | */ | |||
4443 | ||||
4444 | ___device_tty *d = self; | |||
4445 | ___SCMOBJlong e; | |||
4446 | extensible_string *edited = &d->current.hist->edited; | |||
4447 | int screen_size = d->terminal_size; | |||
4448 | int screen_end_of_line = d->current.line_start + edited->length; | |||
4449 | ||||
4450 | if (screen_end_of_line < 0) | |||
4451 | screen_end_of_line = 0; | |||
4452 | else if (screen_end_of_line >= screen_size) | |||
4453 | screen_end_of_line = screen_size - 1; | |||
4454 | ||||
4455 | if ((e = lineeditor_prepare_to_write_at (d, screen_end_of_line)) | |||
4456 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4457 | return e; | |||
4458 | ||||
4459 | return lineeditor_left_margin_of_next_row (d); | |||
4460 | } | |||
4461 | ||||
4462 | ||||
4463 | ___HIDDENstatic ___SCMOBJlong lineeditor_copy_to_clipboard | |||
4464 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, int len) | |||
4465 | ___C *buf,(___device_tty *self, unsigned int *buf, int len) | |||
4466 | int len),(___device_tty *self, unsigned int *buf, int len) | |||
4467 | (self,(___device_tty *self, unsigned int *buf, int len) | |||
4468 | buf,(___device_tty *self, unsigned int *buf, int len) | |||
4469 | len)(___device_tty *self, unsigned int *buf, int len) | |||
4470 | ___device_tty *self;(___device_tty *self, unsigned int *buf, int len) | |||
4471 | ___C *buf;(___device_tty *self, unsigned int *buf, int len) | |||
4472 | int len;)(___device_tty *self, unsigned int *buf, int len) | |||
4473 | { | |||
4474 | /* | |||
4475 | * Copies "len" characters from the buffer "buf" to the clipboard. | |||
4476 | */ | |||
4477 | ||||
4478 | ___device_tty *d = self; | |||
4479 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4480 | ||||
4481 | #ifdef LINEEDITOR_WITH_LOCAL_CLIPBOARD | |||
4482 | ||||
4483 | extensible_string str; | |||
4484 | ||||
4485 | if ((e = extensible_string_copy (buf, len, &str, 0)) == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4486 | { | |||
4487 | extensible_string_cleanup (&d->clipboard); | |||
4488 | d->clipboard = str; | |||
4489 | } | |||
4490 | ||||
4491 | #else | |||
4492 | ||||
4493 | #ifdef USE_WIN32 | |||
4494 | ||||
4495 | HWND cons_wind = GetConsoleWindow (); | |||
4496 | ||||
4497 | if (cons_wind != NULL((void*)0)) | |||
4498 | { | |||
4499 | if (OpenClipboard (cons_wind)) | |||
4500 | { | |||
4501 | HGLOBAL global_copy = GlobalAlloc (GMEM_MOVEABLE, | |||
4502 | (len+1) * sizeof(___U16unsigned short)); | |||
4503 | ||||
4504 | if (global_copy != NULL((void*)0)) | |||
4505 | { | |||
4506 | ___U16unsigned short *locked_copy = ___CAST(___U16*,GlobalLock (global_copy))((unsigned short*)(GlobalLock (global_copy))); | |||
4507 | ||||
4508 | if (locked_copy == NULL((void*)0)) | |||
4509 | GlobalFree (global_copy); | |||
4510 | else | |||
4511 | { | |||
4512 | int i; | |||
4513 | ||||
4514 | for (i=0; i<len; i++) | |||
4515 | locked_copy[i] = buf[i]; | |||
4516 | locked_copy[len] = 0; | |||
4517 | ||||
4518 | GlobalUnlock (global_copy); | |||
4519 | ||||
4520 | EmptyClipboard (); | |||
4521 | ||||
4522 | if (!SetClipboardData (CF_UNICODETEXT, global_copy)) | |||
4523 | GlobalFree (global_copy); | |||
4524 | } | |||
4525 | } | |||
4526 | ||||
4527 | CloseClipboard (); | |||
4528 | } | |||
4529 | } | |||
4530 | ||||
4531 | #endif | |||
4532 | ||||
4533 | #endif | |||
4534 | ||||
4535 | return e; | |||
4536 | } | |||
4537 | ||||
4538 | ||||
4539 | ___HIDDENstatic ___SCMOBJlong lineeditor_paste_from_clipboard | |||
4540 | ___P((___device_tty *self),(___device_tty *self) | |||
4541 | (self)(___device_tty *self) | |||
4542 | ___device_tty *self;)(___device_tty *self) | |||
4543 | { | |||
4544 | /* | |||
4545 | * Paste the content of the clipboard to the input stream (the next | |||
4546 | * characters read from the terminal will in fact come from the | |||
4547 | * pasted text). | |||
4548 | */ | |||
4549 | ||||
4550 | ___device_tty *d = self; | |||
4551 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4552 | ||||
4553 | #ifdef LINEEDITOR_WITH_LOCAL_CLIPBOARD | |||
4554 | ||||
4555 | int len = d->clipboard.length; | |||
4556 | ___Cunsigned int *str; | |||
4557 | ||||
4558 | str = ___CAST(___C*,((unsigned int*)(___alloc_mem ((len+1) * sizeof (unsigned int )))) | |||
4559 | ___alloc_mem ((len+1) * sizeof (___C)))((unsigned int*)(___alloc_mem ((len+1) * sizeof (unsigned int )))); | |||
4560 | ||||
4561 | if (str == NULL((void*)0)) | |||
4562 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
4563 | else | |||
4564 | { | |||
4565 | str[len] = 0; | |||
4566 | while (len-- > 0) | |||
4567 | str[len] = d->clipboard.buffer[len]; | |||
4568 | ||||
4569 | if (d->paste_text != NULL((void*)0)) | |||
4570 | ___free_mem (d->paste_text); | |||
4571 | ||||
4572 | d->paste_index = 0; | |||
4573 | d->paste_text = str; | |||
4574 | } | |||
4575 | ||||
4576 | #else | |||
4577 | ||||
4578 | #ifdef USE_WIN32 | |||
4579 | ||||
4580 | HWND cons_wind = GetConsoleWindow (); | |||
4581 | ||||
4582 | if (cons_wind != NULL((void*)0)) | |||
4583 | { | |||
4584 | if (IsClipboardFormatAvailable (CF_UNICODETEXT) && | |||
4585 | OpenClipboard (cons_wind)) | |||
4586 | { | |||
4587 | HGLOBAL global_copy = GetClipboardData (CF_UNICODETEXT); | |||
4588 | ||||
4589 | if (global_copy != NULL((void*)0)) | |||
4590 | { | |||
4591 | ___U16unsigned short *locked_copy = ___CAST(___U16*,GlobalLock (global_copy))((unsigned short*)(GlobalLock (global_copy))); | |||
4592 | ||||
4593 | if (locked_copy != NULL((void*)0)) | |||
4594 | { | |||
4595 | int i; | |||
4596 | ___Cunsigned int *str; | |||
4597 | int len = 0; | |||
4598 | ||||
4599 | while (locked_copy[len] != 0) | |||
4600 | len++; | |||
4601 | ||||
4602 | str = ___CAST(___C*,((unsigned int*)(___alloc_mem ((len+1) * sizeof (unsigned int )))) | |||
4603 | ___alloc_mem ((len+1) * sizeof (___C)))((unsigned int*)(___alloc_mem ((len+1) * sizeof (unsigned int )))); | |||
4604 | ||||
4605 | if (str == NULL((void*)0)) | |||
4606 | e = ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
4607 | else | |||
4608 | { | |||
4609 | str[len] = 0; | |||
4610 | while (len-- > 0) | |||
4611 | str[len] = locked_copy[len]; | |||
4612 | ||||
4613 | if (d->paste_text != NULL((void*)0)) | |||
4614 | ___free_mem (d->paste_text); | |||
4615 | ||||
4616 | d->paste_index = 0; | |||
4617 | d->paste_text = str; | |||
4618 | } | |||
4619 | ||||
4620 | GlobalUnlock (locked_copy); | |||
4621 | } | |||
4622 | } | |||
4623 | ||||
4624 | CloseClipboard (); | |||
4625 | } | |||
4626 | } | |||
4627 | ||||
4628 | #endif | |||
4629 | ||||
4630 | #endif | |||
4631 | ||||
4632 | return e; | |||
4633 | } | |||
4634 | ||||
4635 | ||||
4636 | ___HIDDENstatic ___BOOLint lineeditor_read_ready | |||
4637 | ___P((___device_tty *self),(___device_tty *self) | |||
4638 | (self)(___device_tty *self) | |||
4639 | ___device_tty *self;)(___device_tty *self) | |||
4640 | { | |||
4641 | ___device_tty *d = self; | |||
4642 | ||||
4643 | return (d->input_char_hi - d->input_char_lo > 0) | |||
4644 | || (d->paste_text != NULL((void*)0)); | |||
4645 | } | |||
4646 | ||||
4647 | ||||
4648 | ___HIDDENstatic ___SCMOBJlong lineeditor_input_read | |||
4649 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4650 | ___C *buf,(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4651 | ___stream_index len,(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4652 | ___stream_index *len_done),(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4653 | (self,(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4654 | buf,(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4655 | len,(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4656 | len_done)(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4657 | ___device_tty *self;(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4658 | ___C *buf;(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4659 | ___stream_index len;(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4660 | ___stream_index *len_done;)(___device_tty *self, unsigned int *buf, ___stream_index len, ___stream_index *len_done) | |||
4661 | { | |||
4662 | ___device_tty *d = self; | |||
4663 | int char_avail = d->input_char_hi - d->input_char_lo; | |||
4664 | ||||
4665 | if (char_avail <= 0) | |||
4666 | { | |||
4667 | /* | |||
4668 | * There are no characters in the character input buffer so we | |||
4669 | * must fill the buffer by reading the device. If possible, | |||
4670 | * characters will be extracted from the byte input buffer | |||
4671 | * without reading new bytes from the device, otherwise the | |||
4672 | * device will be read. If a read error occurs (including | |||
4673 | * EAGAIN) an error code is returned, otherwise ___NO_ERR is | |||
4674 | * returned. ___NO_ERR is returned if and only if at least one | |||
4675 | * character was added to the character buffer. | |||
4676 | */ | |||
4677 | ||||
4678 | ___SCMOBJlong e; | |||
4679 | ___stream_index len; | |||
4680 | ___stream_index len_done; | |||
4681 | ___U8unsigned char *byte_buf; | |||
4682 | int byte_buf_avail; | |||
4683 | int char_buf_avail; | |||
4684 | int lo; | |||
4685 | int code; | |||
4686 | ||||
4687 | /* | |||
4688 | * Make space at end of byte buffer by shifting remaining bytes to | |||
4689 | * the head of the buffer. | |||
4690 | */ | |||
4691 | ||||
4692 | lo = d->input_byte_lo; | |||
4693 | ||||
4694 | if (lo > 0) | |||
4695 | { | |||
4696 | int hi = d->input_byte_hi; | |||
4697 | int i = 0; | |||
4698 | ||||
4699 | while (lo < hi) | |||
4700 | d->input_byte[i++] = d->input_byte[lo++]; | |||
4701 | ||||
4702 | d->input_byte_lo = 0; | |||
4703 | d->input_byte_hi = i; | |||
4704 | } | |||
4705 | ||||
4706 | do | |||
4707 | { | |||
4708 | /* | |||
4709 | * Read as many bytes as possible into the byte buffer. | |||
4710 | */ | |||
4711 | ||||
4712 | if ((e = ___device_tty_read_raw_no_lineeditor | |||
4713 | (d, | |||
4714 | d->input_byte + d->input_byte_hi, | |||
4715 | ___NBELEMS(d->input_byte)(sizeof (d->input_byte) / sizeof ((d->input_byte)[0])) - d->input_byte_hi, | |||
4716 | &len_done)) | |||
4717 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
4718 | return e; | |||
4719 | ||||
4720 | byte_buf_avail = (d->input_byte_hi += len_done) - d->input_byte_lo; | |||
4721 | ||||
4722 | /* | |||
4723 | * Extract as many characters as possible from byte buffer to | |||
4724 | * character buffer. | |||
4725 | */ | |||
4726 | ||||
4727 | if (byte_buf_avail > 0) | |||
4728 | { | |||
4729 | char_buf_avail = ___NBELEMS(d->input_char)(sizeof (d->input_char) / sizeof ((d->input_char)[0])); | |||
4730 | ||||
4731 | code = chars_from_bytes (d->input_char, | |||
4732 | &char_buf_avail, | |||
4733 | d->input_byte + d->input_byte_lo, | |||
4734 | &byte_buf_avail, | |||
4735 | &d->input_decoding_state); | |||
4736 | ||||
4737 | d->input_char_lo = 0; | |||
4738 | d->input_char_hi = ___NBELEMS(d->input_char)(sizeof (d->input_char) / sizeof ((d->input_char)[0])) - char_buf_avail; | |||
4739 | ||||
4740 | if (byte_buf_avail <= 0) | |||
4741 | { | |||
4742 | d->input_byte_lo = 0; | |||
4743 | d->input_byte_hi = 0; | |||
4744 | } | |||
4745 | else | |||
4746 | d->input_byte_lo = d->input_byte_hi - byte_buf_avail; | |||
4747 | ||||
4748 | if (code == ___ILLEGAL_CHAR2) | |||
4749 | return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
4750 | } | |||
4751 | else | |||
4752 | code = ___INCOMPLETE_CHAR1; | |||
4753 | ||||
4754 | } while (code != ___CONVERSION_DONE0); | |||
4755 | ||||
4756 | /* | |||
4757 | * This point is reached if and only if there is at least one | |||
4758 | * character in the character buffer. | |||
4759 | */ | |||
4760 | ||||
4761 | char_avail = d->input_char_hi - d->input_char_lo; | |||
4762 | } | |||
4763 | ||||
4764 | if (char_avail > len) | |||
4765 | char_avail = len; | |||
4766 | ||||
4767 | *len_done = char_avail; | |||
4768 | ||||
4769 | while (char_avail > 0) | |||
4770 | { | |||
4771 | *buf++ = d->input_char[d->input_char_lo++]; | |||
4772 | char_avail--; | |||
4773 | } | |||
4774 | ||||
4775 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4776 | } | |||
4777 | ||||
4778 | ||||
4779 | ___HIDDENstatic ___SCMOBJlong lineeditor_get_event | |||
4780 | ___P((___device_tty *self,(___device_tty *self, lineeditor_event *ev) | |||
4781 | lineeditor_event *ev),(___device_tty *self, lineeditor_event *ev) | |||
4782 | (self,(___device_tty *self, lineeditor_event *ev) | |||
4783 | ev)(___device_tty *self, lineeditor_event *ev) | |||
4784 | ___device_tty *self;(___device_tty *self, lineeditor_event *ev) | |||
4785 | lineeditor_event *ev;)(___device_tty *self, lineeditor_event *ev) | |||
4786 | { | |||
4787 | /* | |||
4788 | * This routine obtains the next line editing event from the | |||
4789 | * terminal. An event can be a key press or some editing operation | |||
4790 | * (like "delete next word"). | |||
4791 | */ | |||
4792 | ||||
4793 | ___device_tty *d = self; | |||
4794 | lineeditor_input_decoder_state s = d->input_decoder_state; | |||
4795 | ___Cunsigned int c; | |||
4796 | ___BOOLint first_char; | |||
4797 | ___stream_index len_done; | |||
4798 | ___SCMOBJlong e; | |||
4799 | ||||
4800 | first_char = (s == 0); | |||
4801 | ||||
4802 | if (d->paste_text != NULL((void*)0)) | |||
4803 | { | |||
4804 | if (d->paste_cancel || | |||
4805 | (c = d->paste_text[d->paste_index++]) == 0) | |||
4806 | { | |||
4807 | ___free_mem (d->paste_text); | |||
4808 | d->paste_text = NULL((void*)0); | |||
4809 | } | |||
4810 | else | |||
4811 | { | |||
4812 | ev->event_kind = LINEEDITOR_EV_KEY1; | |||
4813 | ev->event_char = c; | |||
4814 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4815 | } | |||
4816 | } | |||
4817 | ||||
4818 | next_char: | |||
4819 | ||||
4820 | if ((e = lineeditor_input_read (d, &c, 1, &len_done)) | |||
4821 | == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
4822 | len_done == 1) | |||
4823 | { | |||
4824 | while (s < d->input_decoder.length) | |||
4825 | { | |||
4826 | if (d->input_decoder.buffer[s].trigger == c) | |||
4827 | { | |||
4828 | int a = d->input_decoder.buffer[s].action; | |||
4829 | if (a < LINEEDITOR_INPUT_DECODER_MAX_LENGTH(255 -55 -1)) | |||
4830 | { | |||
4831 | s = a; | |||
4832 | first_char = 0; | |||
4833 | goto next_char; | |||
4834 | } | |||
4835 | d->input_decoder_state = 0; | |||
4836 | ev->event_kind = LINEEDITOR_INPUT_DECODER_STATE_MAX255-a; | |||
4837 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4838 | } | |||
4839 | else | |||
4840 | s = d->input_decoder.buffer[s].next; | |||
4841 | } | |||
4842 | if (first_char) | |||
4843 | { | |||
4844 | ev->event_kind = LINEEDITOR_EV_KEY1; | |||
4845 | ev->event_char = c; | |||
4846 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4847 | } | |||
4848 | s = 0; /* ignore the sequence including last character read */ | |||
4849 | } | |||
4850 | ||||
4851 | d->input_decoder_state = s; | |||
4852 | ev->event_kind = LINEEDITOR_EV_NONE0; | |||
4853 | ||||
4854 | if (e != ___FIX(___NO_ERR)(((long)(0))<<2) && e != ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<< 16)+(11)))))<<2)) | |||
4855 | return e; | |||
4856 | ||||
4857 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
4858 | } | |||
4859 | ||||
4860 | ||||
4861 | ___HIDDENstatic ___SCMOBJlong lineeditor_set_terminal_type | |||
4862 | ___P((___device_tty *self,(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4863 | char *terminal_type,(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4864 | ___BOOL emacs_bindings),(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4865 | (self,(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4866 | terminal_type,(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4867 | emacs_bindings)(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4868 | ___device_tty *self;(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4869 | char *terminal_type;(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4870 | ___BOOL emacs_bindings;)(___device_tty *self, char *terminal_type, int emacs_bindings ) | |||
4871 | { | |||
4872 | ___device_tty *d = self; | |||
4873 | ___SCMOBJlong e; | |||
4874 | ||||
4875 | /* default values appropriate for "xterm": */ | |||
4876 | ||||
4877 | int rows = 24; | |||
4878 | int cols = 80; | |||
4879 | ___BOOLint has_auto_left_margin = 0; | |||
4880 | ___BOOLint has_auto_right_margin = 1; | |||
4881 | ___BOOLint has_eat_newline_glitch = 1; | |||
4882 | ||||
4883 | #ifdef USE_CURSES | |||
4884 | ||||
4885 | int i; | |||
4886 | ||||
4887 | #ifdef USE_TERMCAP_OR_TERMINFO | |||
4888 | ||||
4889 | if (terminal_type != NULL((void*)0)) | |||
4890 | { | |||
4891 | #ifdef USE_TERMCAP | |||
4892 | ||||
4893 | char termcap_buffer[4080]; /* the value 4080 is used by GNU's readline */ | |||
4894 | ||||
4895 | if (tgetent (termcap_buffer, terminal_type) != 1) | |||
4896 | return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
4897 | ||||
4898 | rows = tgetnum ("li"); | |||
4899 | cols = tgetnum ("co"); | |||
4900 | has_auto_left_margin = (tgetflag ("bw") != 0); | |||
4901 | has_auto_right_margin = (tgetflag ("am") != 0); | |||
4902 | has_eat_newline_glitch = (tgetflag ("xn") != 0); | |||
4903 | ||||
4904 | #else | |||
4905 | ||||
4906 | int errret; | |||
4907 | ||||
4908 | if (setupterm (terminal_type, 1, &errret) == ERR) | |||
4909 | return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
4910 | ||||
4911 | rows = tigetnum ("lines"); | |||
4912 | cols = tigetnum ("cols"); | |||
4913 | has_auto_left_margin = (tigetflag ("bw") != 0); | |||
4914 | has_auto_right_margin = (tigetflag ("am") != 0); | |||
4915 | has_eat_newline_glitch = (tigetflag ("xenl") != 0); | |||
4916 | ||||
4917 | #endif | |||
4918 | } | |||
4919 | ||||
4920 | #endif | |||
4921 | ||||
4922 | /* | |||
4923 | * Setup the capability table. | |||
4924 | */ | |||
4925 | ||||
4926 | for (i=0; i<LINEEDITOR_CAP_LAST21+1; i++) | |||
4927 | { | |||
4928 | char *seq = d->capability[i]; | |||
4929 | ||||
4930 | if (seq != NULL((void*)0)) | |||
4931 | { | |||
4932 | ___free_mem (seq); | |||
4933 | d->capability[i] = NULL((void*)0); | |||
4934 | } | |||
4935 | } | |||
4936 | ||||
4937 | for (i=0; i<LINEEDITOR_CAP_LAST21+1; i++) | |||
4938 | { | |||
4939 | char *seq; | |||
4940 | ||||
4941 | #ifdef USE_TERMCAP_OR_TERMINFO | |||
4942 | ||||
4943 | if (terminal_type != NULL((void*)0)) | |||
4944 | { | |||
4945 | #ifdef USE_TERMCAP | |||
4946 | ||||
4947 | seq = tgetstr (lineeditor_dcap_table[i].cap, NULL((void*)0)); | |||
4948 | ||||
4949 | #else | |||
4950 | ||||
4951 | seq = tigetstr (lineeditor_dcap_table[i].cap); | |||
4952 | ||||
4953 | #endif | |||
4954 | } | |||
4955 | else | |||
4956 | seq = lineeditor_dcap_table[i].xterm_cap; | |||
4957 | ||||
4958 | #else | |||
4959 | ||||
4960 | seq = lineeditor_dcap_table[i].cap; | |||
4961 | ||||
4962 | #endif | |||
4963 | ||||
4964 | if (seq != (char*)-1 && seq != NULL((void*)0)) | |||
4965 | { | |||
4966 | #ifdef ___DEBUG_TTY | |||
4967 | ||||
4968 | int j = -1; | |||
4969 | ||||
4970 | ___printf ("cap %d = ", i); | |||
4971 | ||||
4972 | while (seq[++j] != '\0') | |||
4973 | if (seq[j] < ' ') | |||
4974 | ___printf ("\\%03o", seq[j]); | |||
4975 | else | |||
4976 | ___printf ("%c", seq[j]); | |||
4977 | ||||
4978 | ___printf ("\n"); | |||
4979 | ||||
4980 | #endif | |||
4981 | ||||
4982 | /* | |||
4983 | * Reject any sequence that includes a linefeed if the | |||
4984 | * terminal driver automatically adds a carriage return. | |||
4985 | */ | |||
4986 | ||||
4987 | if (d->linefeed_moves_to_left_margin) | |||
4988 | { | |||
4989 | char *p = seq; | |||
4990 | while (*p != '\0') | |||
4991 | if (*p != ___UNICODE_LINEFEED10) | |||
4992 | p++; | |||
4993 | else | |||
4994 | break; | |||
4995 | if (*p != '\0') | |||
4996 | seq = NULL((void*)0); | |||
4997 | } | |||
4998 | ||||
4999 | /* | |||
5000 | * Keep a copy of the sequence. | |||
5001 | */ | |||
5002 | ||||
5003 | if (seq != NULL((void*)0)) | |||
5004 | { | |||
5005 | char *p; | |||
5006 | int len = 0; | |||
5007 | while (seq[len] != '\0') | |||
5008 | len++; | |||
5009 | p = ___CAST(char*,___alloc_mem (len+1))((char*)(___alloc_mem (len+1))); | |||
5010 | if (p != NULL((void*)0)) | |||
5011 | { | |||
5012 | p[len] = '\0'; | |||
5013 | while (len-- > 0) | |||
5014 | p[len] = seq[len]; | |||
5015 | } | |||
5016 | d->capability[i] = p; | |||
5017 | } | |||
5018 | else | |||
5019 | d->capability[i] = NULL((void*)0); | |||
5020 | } | |||
5021 | else | |||
5022 | d->capability[i] = NULL((void*)0); | |||
5023 | } | |||
5024 | ||||
5025 | #endif | |||
5026 | ||||
5027 | /* | |||
5028 | * Initialize input decoder so that it recognizes special keys. Map | |||
5029 | * rubout key to backspace if not on WIN32. | |||
5030 | */ | |||
5031 | ||||
5032 | d->input_decoder_state = 0; | |||
5033 | ||||
5034 | if ((e = lineeditor_input_decoder_init | |||
5035 | (&d->input_decoder, | |||
5036 | #ifdef USE_WIN32 | |||
5037 | 0, | |||
5038 | #else | |||
5039 | 1, | |||
5040 | #endif | |||
5041 | emacs_bindings, | |||
5042 | terminal_type == NULL((void*)0))) | |||
5043 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5044 | return e; | |||
5045 | ||||
5046 | if (rows <= 0) | |||
5047 | rows = 24; | |||
5048 | if (cols <= 0) | |||
5049 | cols = 80; | |||
5050 | ||||
5051 | d->terminal_nb_cols = cols; | |||
5052 | d->terminal_nb_rows = rows; | |||
5053 | d->terminal_size = rows * cols; | |||
5054 | d->has_auto_left_margin = has_auto_left_margin; | |||
5055 | d->has_auto_right_margin = has_auto_right_margin; | |||
5056 | d->has_eat_newline_glitch = has_eat_newline_glitch; | |||
5057 | d->size_needs_update = 1; | |||
5058 | ||||
5059 | #ifdef ___DEBUG_TTY | |||
5060 | ||||
5061 | ___printf ("terminal_type=%s rows=%d cols=%d alm=%d arm=%d eng=%d\n", | |||
5062 | terminal_type, | |||
5063 | rows, | |||
5064 | cols, | |||
5065 | has_auto_left_margin, | |||
5066 | has_auto_right_margin, | |||
5067 | has_eat_newline_glitch); | |||
5068 | ||||
5069 | #endif | |||
5070 | ||||
5071 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
5072 | } | |||
5073 | ||||
5074 | ||||
5075 | ___HIDDENstatic ___SCMOBJlong ___device_tty_default_options_virt | |||
5076 | ___P((___device_stream *self),(___device_stream *self) | |||
5077 | ())(___device_stream *self); | |||
5078 | ||||
5079 | ||||
5080 | ___HIDDENstatic ___SCMOBJlong lineeditor_setup | |||
5081 | ___P((___device_tty *self,(___device_tty *self, int plain) | |||
5082 | int plain),(___device_tty *self, int plain) | |||
5083 | (self,(___device_tty *self, int plain) | |||
5084 | plain)(___device_tty *self, int plain) | |||
5085 | ___device_tty *self;(___device_tty *self, int plain) | |||
5086 | int plain;)(___device_tty *self, int plain) | |||
5087 | { | |||
5088 | ___device_tty *d = self; | |||
5089 | ___SCMOBJlong e; | |||
5090 | lineeditor_history *h; | |||
5091 | ___SCMOBJlong default_options = | |||
5092 | ___INT(___device_tty_default_options_virt (&d->base))((___device_tty_default_options_virt (&d->base))>> 2); | |||
5093 | ||||
5094 | if (plain || d->stage == TTY_STAGE_NOT_OPENED0) | |||
5095 | { | |||
5096 | /* Console */ | |||
5097 | ||||
5098 | d->input_allow_special = 1; | |||
5099 | d->input_echo = 1; | |||
5100 | d->input_raw = 0; | |||
5101 | d->output_raw = 0; | |||
5102 | d->speed = 0; | |||
5103 | } | |||
5104 | else | |||
5105 | { | |||
5106 | /* TTY other than console */ | |||
5107 | ||||
5108 | d->input_allow_special = 0; | |||
5109 | d->input_echo = 0; | |||
5110 | d->input_raw = 1; | |||
5111 | d->output_raw = 1; | |||
5112 | d->speed = 0; | |||
5113 | } | |||
5114 | ||||
5115 | d->lineeditor_mode = LINEEDITOR_MODE_DISABLE0; | |||
5116 | ||||
5117 | if (lineeditor_under_emacs ()) | |||
5118 | d->input_echo = 0; | |||
5119 | else | |||
5120 | { | |||
5121 | if (___TERMINAL_LINE_EDITING(___setup_params.terminal_settings)((___setup_params.terminal_settings)&(3<<16)) != | |||
5122 | ___TERMINAL_LINE_EDITING_OFF(2<<16)) | |||
5123 | d->lineeditor_mode = LINEEDITOR_MODE_SCHEME1; | |||
5124 | } | |||
5125 | ||||
5126 | /* for terminal emulation */ | |||
5127 | ||||
5128 | d->emulate_terminal = 1; | |||
5129 | ||||
5130 | d->terminal_nb_cols = 80; | |||
5131 | d->terminal_nb_rows = 24; | |||
5132 | d->terminal_size = d->terminal_nb_rows * d->terminal_nb_cols; | |||
5133 | d->has_auto_left_margin = 0; | |||
5134 | d->has_auto_right_margin = 1; | |||
5135 | d->has_eat_newline_glitch = 1; | |||
5136 | d->linefeed_moves_to_left_margin = 0; | |||
5137 | ||||
5138 | d->terminal_col = 0; | |||
5139 | d->terminal_row = 0; | |||
5140 | d->terminal_cursor = 0; | |||
5141 | d->terminal_delayed_wrap = 0; | |||
5142 | ||||
5143 | d->terminal_param_num = -2; | |||
5144 | ||||
5145 | d->terminal_attrs = MAKE_TEXT_ATTRS(TEXT_STYLE_NORMAL,(((0)<<8)+(8)+((8)<<4)) | |||
5146 | DEFAULT_TEXT_COLOR,(((0)<<8)+(8)+((8)<<4)) | |||
5147 | DEFAULT_TEXT_COLOR)(((0)<<8)+(8)+((8)<<4)); | |||
5148 | ||||
5149 | /* input and output buffers */ | |||
5150 | ||||
5151 | d->input_byte_lo = 0; | |||
5152 | d->input_byte_hi = 0; | |||
5153 | d->input_char_lo = 0; | |||
5154 | d->input_char_hi = 0; | |||
5155 | ||||
5156 | d->input_decoding_state = ___STREAM_OPTIONS_INPUT(default_options)((default_options)&((1<<15)-1)); | |||
5157 | d->input_encoding_state = ___STREAM_OPTIONS_INPUT(default_options)((default_options)&((1<<15)-1)); | |||
5158 | ||||
5159 | d->input_line_lo = 0; | |||
5160 | d->input_line.buffer = NULL((void*)0); | |||
5161 | d->input_line.length = 0; | |||
5162 | ||||
5163 | d->output_byte_lo = 0; | |||
5164 | d->output_byte_hi = 0; | |||
5165 | ||||
5166 | d->output_char_incomplete = 0; | |||
5167 | d->input_char_incomplete = 0; | |||
5168 | ||||
5169 | d->output_decoding_state = ___STREAM_OPTIONS_OUTPUT(default_options)(((default_options)>>15)&((1<<15)-1)); | |||
5170 | d->output_encoding_state = ___STREAM_OPTIONS_OUTPUT(default_options)(((default_options)>>15)&((1<<15)-1)); | |||
5171 | ||||
5172 | d->output_char_lo = 0; | |||
5173 | ||||
5174 | /* line editing */ | |||
5175 | ||||
5176 | d->editing_line = 0; | |||
5177 | ||||
5178 | d->prompt_length = 0; | |||
5179 | ||||
5180 | d->lineeditor_input_byte_lo = 0; | |||
5181 | d->lineeditor_input_byte_hi = 0; | |||
5182 | ||||
5183 | d->paste_cancel = 0; | |||
5184 | d->paste_index = 0; | |||
5185 | d->paste_text = NULL((void*)0); | |||
5186 | ||||
5187 | d->history_max_length = 1000000000; /* set a very high limit */ | |||
5188 | d->history_length = -1; | |||
5189 | d->hist_last = NULL((void*)0); | |||
5190 | ||||
5191 | d->current.edit_point = 0; | |||
5192 | d->current.completion_point = 0; | |||
5193 | d->current.mark_point = 0; | |||
5194 | d->current.line_start = 0; | |||
5195 | d->current.paren_balance_trigger = 0; | |||
5196 | d->current.paren_balance_in_progress = 0; | |||
5197 | d->current.attrs = INITIAL_TEXT_ATTRS(((0)<<8)+(8)+((8)<<4)); | |||
5198 | ||||
5199 | d->paren_balance_duration_nsecs = DEFAULT_PAREN_BALANCE_DURATION_NSECS500000000; | |||
5200 | ||||
5201 | d->input_attrs = DEFAULT_INPUT_TEXT_ATTRS(((1)<<8)+(8)+((8)<<4)); | |||
5202 | d->output_attrs = DEFAULT_OUTPUT_TEXT_ATTRS(((0)<<8)+(8)+((8)<<4)); | |||
5203 | ||||
5204 | #ifdef USE_CURSES | |||
5205 | ||||
5206 | { | |||
5207 | int i; | |||
5208 | for (i=0; i<LINEEDITOR_CAP_LAST21+1; i++) | |||
5209 | d->capability[i] = NULL((void*)0); | |||
5210 | } | |||
5211 | ||||
5212 | #endif | |||
5213 | ||||
5214 | #ifdef USE_WIN32 | |||
5215 | ||||
5216 | d->key_seq = NULL((void*)0); | |||
5217 | ||||
5218 | #endif | |||
5219 | ||||
5220 | #ifdef LINEEDITOR_WITH_LOCAL_CLIPBOARD | |||
5221 | if ((e = extensible_string_setup (&d->clipboard, 0)) | |||
5222 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5223 | { | |||
5224 | #endif | |||
5225 | if ((e = extensible_string_setup (&d->output_char, 0)) | |||
5226 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5227 | { | |||
5228 | if ((e = lineeditor_input_decoder_setup (&d->input_decoder)) | |||
5229 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5230 | { | |||
5231 | if ((e = lineeditor_history_setup (d, &h)) | |||
5232 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5233 | { | |||
5234 | lineeditor_history_add_last (d, h); | |||
5235 | d->current.hist = h; | |||
5236 | if ((e = lineeditor_history_begin_edit (d, h)) | |||
5237 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5238 | { | |||
5239 | if ((e = lineeditor_set_terminal_type | |||
5240 | (d, | |||
5241 | NULL((void*)0), | |||
5242 | DEFAULT_EMACS_BINDINGS1)) | |||
5243 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5244 | { | |||
5245 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
5246 | } | |||
5247 | } | |||
5248 | d->history_max_length = -1; | |||
5249 | lineeditor_history_trim (d); | |||
5250 | } | |||
5251 | lineeditor_input_decoder_cleanup (&d->input_decoder); | |||
5252 | } | |||
5253 | extensible_string_cleanup (&d->output_char); | |||
5254 | } | |||
5255 | #ifdef LINEEDITOR_WITH_LOCAL_CLIPBOARD | |||
5256 | extensible_string_cleanup (&d->clipboard); | |||
5257 | } | |||
5258 | #endif | |||
5259 | ||||
5260 | return e; | |||
5261 | } | |||
5262 | ||||
5263 | ||||
5264 | ___HIDDENstatic void lineeditor_cleanup | |||
5265 | ___P((___device_tty *self),(___device_tty *self) | |||
5266 | (self)(___device_tty *self) | |||
5267 | ___device_tty *self;)(___device_tty *self) | |||
5268 | { | |||
5269 | ___device_tty *d = self; | |||
5270 | ||||
5271 | #ifdef USE_CURSES | |||
5272 | { | |||
5273 | int i; | |||
5274 | ||||
5275 | for (i=0; i<LINEEDITOR_CAP_LAST21+1; i++) | |||
5276 | { | |||
5277 | char *seq = d->capability[i]; | |||
5278 | if (seq != NULL((void*)0)) | |||
5279 | ___free_mem (seq); | |||
5280 | } | |||
5281 | } | |||
5282 | #endif | |||
5283 | ||||
5284 | d->history_max_length = -1; | |||
5285 | lineeditor_history_trim (d); | |||
5286 | ||||
5287 | lineeditor_input_decoder_cleanup (&d->input_decoder); | |||
5288 | ||||
5289 | extensible_string_cleanup (&d->output_char); | |||
5290 | ||||
5291 | #ifdef LINEEDITOR_WITH_LOCAL_CLIPBOARD | |||
5292 | extensible_string_cleanup (&d->clipboard); | |||
5293 | #endif | |||
5294 | ||||
5295 | if (d->input_line.buffer != NULL((void*)0)) | |||
5296 | extensible_string_cleanup (&d->input_line); | |||
5297 | ||||
5298 | lineeditor_output_set_attrs | |||
5299 | (d, | |||
5300 | INITIAL_TEXT_ATTRS(((0)<<8)+(8)+((8)<<4))); /* ignore error */ | |||
5301 | ||||
5302 | lineeditor_output_drain (d); /* ignore error */ | |||
5303 | ||||
5304 | if (d->paste_text != NULL((void*)0)) | |||
5305 | ___free_mem (d->paste_text); /* discard paste text */ | |||
5306 | ||||
5307 | #if 0 | |||
5308 | /******************** device should be freed elsewhere */ | |||
5309 | ___free_mem (d); | |||
5310 | #endif | |||
5311 | } | |||
5312 | ||||
5313 | ||||
5314 | /* | |||
5315 | * Each character position of the screen is identified by an integer | |||
5316 | * from 0 to nb_rows * nb_cols - 1. Screen position 0 is at the top | |||
5317 | * left. This numbering is logically extended beyond the actual | |||
5318 | * screen limits. If we assume that the screen is 10 columns by 4 | |||
5319 | * rows we have this layout: | |||
5320 | * | |||
5321 | * | |||
5322 | * ... -8 -7 -6 -5 -4 -3 -2 -1 | |||
5323 | * OFF SCREEN | |||
5324 | * +---+---+---+---+---+---+---+---+---+---+^^^^^^^^^^^^ | |||
5325 | * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | \ | |||
5326 | * +---+---+---+---+---+---+---+---+---+---+ | | |||
5327 | * |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 | | | |||
5328 | * +---+---+---+---+---+---+---+---+---+---+ > SCREEN | |||
5329 | * |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 | | | |||
5330 | * +---+---+---+---+---+---+---+---+---+---+ | | |||
5331 | * |30 |31 |32 |33 |34 |35 |36 |37 |38 |39 | / | |||
5332 | * +---+---+---+---+---+---+---+---+---+---+vvvvvvvvvvvv | |||
5333 | * OFF SCREEN | |||
5334 | * 40 41 42 43 44 45 46 47 ... | |||
5335 | * | |||
5336 | * The "cursor" position is the screen position where the cursor is | |||
5337 | * currently located. The field terminal_cursor contains this | |||
5338 | * screen position (the fields terminal_col and terminal_row | |||
5339 | * indicate the column and row of the cursor). | |||
5340 | * | |||
5341 | * The line that is being edited usually fits completely on the screen | |||
5342 | * but if the line is very long some parts may not be visible. When | |||
5343 | * an editing operation causes the cursor to move the edited line is | |||
5344 | * redisplayed so that the cursor stays visible. | |||
5345 | * | |||
5346 | * The editing "point" is the character position in the line being | |||
5347 | * edited where editing operations occur (inserting characters, etc). | |||
5348 | * The cursor is usually over the character at the editing point. | |||
5349 | * Some operations, notably parenthesis balancing and program output, | |||
5350 | * move the cursor over some other character than the editing point. | |||
5351 | * | |||
5352 | * The field "line_start" contains the (logical) screen position where | |||
5353 | * the edited line starts. Here is an example where the edited line | |||
5354 | * starts at screen position 18 and is 15 characters long. | |||
5355 | * | |||
5356 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5357 | * | H | e | l | l | o | . | | | | | | |||
5358 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5359 | * | P | R | O | M | P | T | > | | 0 | 1 | | |||
5360 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5361 | * | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 | | |||
5362 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5363 | * |12 |13 |14 | | | | | | | | | |||
5364 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5365 | * | |||
5366 | * Here is an example where the edited line is larger than the | |||
5367 | * screen (the edited line starts at screen position -22 and | |||
5368 | * it contains 65 characters). | |||
5369 | * | |||
5370 | * | |||
5371 | * P R O M P T > 0 1 | |||
5372 | * | |||
5373 | * 2 3 4 5 6 7 8 9 10 11 | |||
5374 | * | |||
5375 | * 12 13 14 15 16 17 18 19 20 21 | |||
5376 | * OFF SCREEN | |||
5377 | * +---+---+---+---+---+---+---+---+---+---+^^^^^^^^^^^^ | |||
5378 | * |22 |23 |24 |25 |26 |27 |28 |29 |30 |31 | \ | |||
5379 | * +---+---+---+---+---+---+---+---+---+---+ | | |||
5380 | * |32 | . | . | . | . | . | . | . | . |41 | | | |||
5381 | * +---+---+---+---+---+---+---+---+---+---+ > SCREEN | |||
5382 | * |42 | . | . | . | . | . | . | . | . |51 | | | |||
5383 | * +---+---+---+---+---+---+---+---+---+---+ | | |||
5384 | * |52 |53 |54 |55 |56 |57 |58 |59 |60 |61 | / | |||
5385 | * +---+---+---+---+---+---+---+---+---+---+vvvvvvvvvvvv | |||
5386 | * OFF SCREEN | |||
5387 | * 62 63 64 | |||
5388 | */ | |||
5389 | ||||
5390 | ||||
5391 | ___HIDDENstatic ___SCMOBJlong lineeditor_update_region | |||
5392 | ___P((___device_tty *self,(___device_tty *self, int start, int end) | |||
5393 | int start,(___device_tty *self, int start, int end) | |||
5394 | int end),(___device_tty *self, int start, int end) | |||
5395 | (self,(___device_tty *self, int start, int end) | |||
5396 | start,(___device_tty *self, int start, int end) | |||
5397 | end)(___device_tty *self, int start, int end) | |||
5398 | ___device_tty *self;(___device_tty *self, int start, int end) | |||
5399 | int start;(___device_tty *self, int start, int end) | |||
5400 | int end;)(___device_tty *self, int start, int end) | |||
5401 | { | |||
5402 | /* | |||
5403 | * This routine is called when a change in the line being edited | |||
5404 | * must be shown on the screen. Characters between positions | |||
5405 | * "start" (inclusive) and "end" (exclusive) have changed. Only the | |||
5406 | * changes that are visible cause the screen to be updated. | |||
5407 | */ | |||
5408 | ||||
5409 | ___device_tty *d = self; | |||
5410 | ___SCMOBJlong e; | |||
5411 | int screen_size = d->terminal_size; | |||
5412 | int screen_start = d->current.line_start + start; | |||
5413 | int screen_end = d->current.line_start + end; | |||
5414 | ||||
5415 | if (!d->has_eat_newline_glitch) | |||
5416 | screen_size--; /* the last character on the screen can't be shown! */ | |||
5417 | ||||
5418 | if (screen_start >= screen_size || | |||
5419 | screen_end <= 0) | |||
5420 | e = ___FIX(___NO_ERR)(((long)(0))<<2); /* the change is not visible */ | |||
5421 | else | |||
5422 | { | |||
5423 | if (screen_start < 0) | |||
5424 | screen_start = 0; | |||
5425 | ||||
5426 | if (screen_end > screen_size) | |||
5427 | screen_end = screen_size; | |||
5428 | ||||
5429 | if ((e = lineeditor_prepare_to_write_at (d, screen_start)) | |||
5430 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5431 | e = lineeditor_output_current_hist | |||
5432 | (d, | |||
5433 | screen_start - d->current.line_start, | |||
5434 | screen_end - screen_start); | |||
5435 | } | |||
5436 | ||||
5437 | return e; | |||
5438 | } | |||
5439 | ||||
5440 | ||||
5441 | ___HIDDENstatic ___SCMOBJlong lineeditor_output_prompt | |||
5442 | ___P((___device_tty *self),(___device_tty *self) | |||
5443 | (self)(___device_tty *self) | |||
5444 | ___device_tty *self;)(___device_tty *self) | |||
5445 | { | |||
5446 | /* | |||
5447 | * This routine outputs the prompt that was output by the program | |||
5448 | * before line editing started. | |||
5449 | */ | |||
5450 | ||||
5451 | ___device_tty *d = self; | |||
5452 | ||||
5453 | if (d->prompt_length < ___CAST(int,___NBELEMS(d->prompt))((int)((sizeof (d->prompt) / sizeof ((d->prompt)[0]))))) | |||
5454 | return lineeditor_output (d, d->prompt, d->prompt_length); | |||
5455 | ||||
5456 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
5457 | } | |||
5458 | ||||
5459 | ||||
5460 | ___HIDDENstatic ___SCMOBJlong lineeditor_move_edit_point | |||
5461 | ___P((___device_tty *self,(___device_tty *self, int pos) | |||
5462 | int pos),(___device_tty *self, int pos) | |||
5463 | (self,(___device_tty *self, int pos) | |||
5464 | pos)(___device_tty *self, int pos) | |||
5465 | ___device_tty *self;(___device_tty *self, int pos) | |||
5466 | int pos;)(___device_tty *self, int pos) | |||
5467 | { | |||
5468 | /* | |||
5469 | * Moves the editing point of the line being edited. The screen | |||
5470 | * may get scrolled in order to keep the editing point visible. | |||
5471 | */ | |||
5472 | ||||
5473 | ___device_tty *d = self; | |||
5474 | ___SCMOBJlong e; | |||
5475 | extensible_string *edited = &d->current.hist->edited; | |||
5476 | int cursor; | |||
5477 | int screen_nb_cols; | |||
5478 | int screen_nb_rows; | |||
5479 | int screen_size; | |||
5480 | int cursor_row; | |||
5481 | int first_row; | |||
5482 | int last_row; | |||
5483 | int scroll_rows; | |||
5484 | int all_fits; | |||
5485 | int n; | |||
5486 | int start; | |||
5487 | ||||
5488 | if (pos < 0 || | |||
5489 | pos > edited->length) | |||
5490 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
5491 | ||||
5492 | screen_nb_cols = d->terminal_nb_cols; | |||
5493 | screen_nb_rows = d->terminal_nb_rows; | |||
5494 | screen_size = d->terminal_size; | |||
5495 | cursor = d->current.line_start + pos; /* new cursor position in screen */ | |||
5496 | ||||
5497 | cursor_row = cursor; | |||
5498 | if (cursor_row < 0) | |||
5499 | cursor_row -= screen_nb_cols - 1; | |||
5500 | cursor_row /= screen_nb_cols; | |||
5501 | ||||
5502 | first_row = d->current.line_start; | |||
5503 | if (first_row < 0) | |||
5504 | first_row -= screen_nb_cols - 1; | |||
5505 | first_row /= screen_nb_cols; | |||
5506 | ||||
5507 | last_row = d->current.line_start + edited->length; | |||
5508 | if (last_row < 0) | |||
5509 | last_row -= screen_nb_cols - 1; | |||
5510 | last_row /= screen_nb_cols; | |||
5511 | ||||
5512 | /* | |||
5513 | * Here is an example where the edited line contains 25 characters, | |||
5514 | * the edited line starts at position 18, and pos = 11: | |||
5515 | * | |||
5516 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5517 | * | H | e | l | l | o | . | | | | | | |||
5518 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5519 | * | P | R | O | M | P | T | > | | 0 | 1 | first_row = 1 | |||
5520 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5521 | * | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 | cursor_row = 2 | |||
5522 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5523 | * |12 |13 |14 |15 |16 |17 |18 |19 |20 |21 | | |||
5524 | * +---+---+---+---+---+---+---+---+---+---+ | |||
5525 | * | |||
5526 | * 22 23 24 last_row = 4 | |||
5527 | */ | |||
5528 | ||||
5529 | /* | |||
5530 | * Check if the text from the cursor to the position just after end | |||
5531 | * of the edited line can all fit on the screen (while maintaining | |||
5532 | * column alignment). | |||
5533 | */ | |||
5534 | ||||
5535 | all_fits = (last_row - cursor_row < screen_nb_rows); | |||
5536 | ||||
5537 | /* | |||
5538 | * Determine how many rows to scroll and in which direction | |||
5539 | * (scroll_rows is positive when scrolling forward and negative when | |||
5540 | * scrolling backward). | |||
5541 | */ | |||
5542 | ||||
5543 | if (all_fits) | |||
5544 | { | |||
5545 | /* | |||
5546 | * The region of the edited line between the cursor and end can | |||
5547 | * fit on the screen at the same time. | |||
5548 | */ | |||
5549 | ||||
5550 | if (cursor_row >= 0 && | |||
5551 | last_row < screen_nb_rows) | |||
5552 | /* Don't scroll if text from cursor to end is visible right now. */ | |||
5553 | scroll_rows = 0; | |||
5554 | else | |||
5555 | /* Scroll so that last row of edited line is at bottom of screen. */ | |||
5556 | scroll_rows = last_row - (screen_nb_rows - 1); | |||
5557 | } | |||
5558 | else | |||
5559 | { | |||
5560 | /* | |||
5561 | * The region of the edited line between the cursor and end cannot | |||
5562 | * fit on the screen at the same time. | |||
5563 | */ | |||
5564 | ||||
5565 | if (cursor_row >= 0 && | |||
5566 | cursor_row < screen_nb_rows) | |||
5567 | /* Don't scroll if cursor is visible right now. */ | |||
5568 | scroll_rows = 0; | |||
5569 | else | |||
5570 | { | |||
5571 | /* | |||
5572 | * Scroll cursor row to bottom of screen unless this would | |||
5573 | * make a line before the line start visible, in which case | |||
5574 | * align the line start to the top of the screen. | |||
5575 | */ | |||
5576 | ||||
5577 | scroll_rows = cursor_row - (screen_nb_rows - 1); | |||
5578 | ||||
5579 | if (scroll_rows < first_row) | |||
5580 | scroll_rows = first_row; | |||
5581 | } | |||
5582 | } | |||
5583 | ||||
5584 | /* | |||
5585 | * Perform scrolling of screen. | |||
5586 | */ | |||
5587 | ||||
5588 | if (scroll_rows != 0) | |||
5589 | { | |||
5590 | cursor -= screen_nb_cols * scroll_rows; | |||
5591 | ||||
5592 | if (scroll_rows < 0) | |||
5593 | { | |||
5594 | /* scroll screen backward by whole rows */ | |||
5595 | ||||
5596 | start = pos - cursor; | |||
5597 | ||||
5598 | n = screen_size; /* write to the whole screen */ | |||
5599 | ||||
5600 | if ((e = lineeditor_prepare_to_write_at (d, 0)) | |||
5601 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5602 | return e; | |||
5603 | ||||
5604 | if ((e = lineeditor_output_prompt (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5605 | return e; | |||
5606 | } | |||
5607 | else | |||
5608 | { | |||
5609 | /* scroll screen forward by whole rows */ | |||
5610 | ||||
5611 | start = screen_size - d->current.line_start; | |||
5612 | ||||
5613 | n = screen_nb_cols * scroll_rows; /* write characters that scroll in */ | |||
5614 | ||||
5615 | if ((e = lineeditor_prepare_to_write_at (d, screen_size)) | |||
5616 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5617 | return e; | |||
5618 | } | |||
5619 | ||||
5620 | if (!d->has_eat_newline_glitch) | |||
5621 | n--; /* to avoid wraparound at end of screen */ | |||
5622 | ||||
5623 | if (n > edited->length - start) | |||
5624 | n = edited->length - start; | |||
5625 | ||||
5626 | if ((e = lineeditor_output_current_hist (d, start, n)) | |||
5627 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5628 | return e; | |||
5629 | } | |||
5630 | ||||
5631 | if (all_fits) | |||
5632 | if ((e = lineeditor_output_force_delayed_wrap (d)) | |||
5633 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5634 | return e; | |||
5635 | ||||
5636 | if ((e = lineeditor_move_cursor (d, cursor)) | |||
5637 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5638 | return e; | |||
5639 | ||||
5640 | d->current.edit_point = pos; | |||
5641 | d->current.completion_point = pos; | |||
5642 | ||||
5643 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
5644 | } | |||
5645 | ||||
5646 | ||||
5647 | ___HIDDENstatic ___SCMOBJlong lineeditor_refresh | |||
5648 | ___P((___device_tty *self),(___device_tty *self) | |||
5649 | (self)(___device_tty *self) | |||
5650 | ___device_tty *self;)(___device_tty *self) | |||
5651 | { | |||
5652 | ___device_tty *d = self; | |||
5653 | ___SCMOBJlong e; | |||
5654 | extensible_string *edited = &d->current.hist->edited; | |||
5655 | ||||
5656 | if ((e = lineeditor_output_set_attrs | |||
5657 | (d, | |||
5658 | lineeditor_erase_attrs (d))) | |||
5659 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5660 | { | |||
5661 | #ifdef USE_CURSES | |||
5662 | ||||
5663 | if (lineeditor_cap (d, LINEEDITOR_CAP_CLEAR1) != NULL((void*)0)) | |||
5664 | e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_CLEAR1, 1); | |||
5665 | else | |||
5666 | ||||
5667 | #endif | |||
5668 | ||||
5669 | e = lineeditor_left_margin_of_next_row (d); | |||
5670 | ||||
5671 | if (e == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5672 | { | |||
5673 | lineeditor_output_prompt (d); /* ignore error */ | |||
5674 | ||||
5675 | d->current.line_start = d->terminal_cursor; | |||
5676 | ||||
5677 | if ((e = lineeditor_update_region (d, 0, edited->length)) | |||
5678 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5679 | e = lineeditor_move_edit_point (d, d->current.edit_point); | |||
5680 | } | |||
5681 | } | |||
5682 | ||||
5683 | return e; | |||
5684 | } | |||
5685 | ||||
5686 | ||||
5687 | ___HIDDENstatic ___SCMOBJlong lineeditor_redraw | |||
5688 | ___P((___device_tty *self),(___device_tty *self) | |||
5689 | (self)(___device_tty *self) | |||
5690 | ___device_tty *self;)(___device_tty *self) | |||
5691 | { | |||
5692 | ___device_tty *d = self; | |||
5693 | ___SCMOBJlong e; | |||
5694 | extensible_string *edited = &d->current.hist->edited; | |||
5695 | int prompt_start = d->current.line_start - d->prompt_length; | |||
5696 | ||||
5697 | if (prompt_start < 0) | |||
5698 | prompt_start = 0; | |||
5699 | ||||
5700 | if ((e = lineeditor_output_set_attrs | |||
5701 | (d, | |||
5702 | lineeditor_erase_attrs (d))) | |||
5703 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5704 | { | |||
5705 | if ((e = lineeditor_move_cursor (d, prompt_start)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5706 | return e; | |||
5707 | ||||
5708 | #ifdef USE_CURSES | |||
5709 | ||||
5710 | if (lineeditor_cap (d, LINEEDITOR_CAP_ED15) != NULL((void*)0)) | |||
5711 | e = lineeditor_output_cap0 (d, LINEEDITOR_CAP_ED15, 1); | |||
5712 | ||||
5713 | #endif | |||
5714 | ||||
5715 | if ((e = lineeditor_output_prompt (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5716 | return e; | |||
5717 | ||||
5718 | d->current.line_start = d->terminal_cursor; | |||
5719 | ||||
5720 | if ((e = lineeditor_update_region (d, 0, edited->length)) | |||
5721 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
5722 | e = lineeditor_move_edit_point (d, d->current.edit_point); | |||
5723 | } | |||
5724 | ||||
5725 | return e; | |||
5726 | } | |||
5727 | ||||
5728 | ||||
5729 | #define FORW_WORD0 0 | |||
5730 | #define BACK_WORD1 1 | |||
5731 | #define FORW_SEXPR2 2 | |||
5732 | #define BACK_SEXPR3 3 | |||
5733 | #define BACK_SEXPR_PAREN4 4 | |||
5734 | ||||
5735 | ___HIDDENstatic ___BOOLint lineeditor_word_boundary | |||
5736 | ___P((___device_tty *self,(___device_tty *self, int dir, int pos, int *final_pos) | |||
5737 | int dir,(___device_tty *self, int dir, int pos, int *final_pos) | |||
5738 | int pos,(___device_tty *self, int dir, int pos, int *final_pos) | |||
5739 | int *final_pos),(___device_tty *self, int dir, int pos, int *final_pos) | |||
5740 | (self,(___device_tty *self, int dir, int pos, int *final_pos) | |||
5741 | dir,(___device_tty *self, int dir, int pos, int *final_pos) | |||
5742 | pos,(___device_tty *self, int dir, int pos, int *final_pos) | |||
5743 | final_pos)(___device_tty *self, int dir, int pos, int *final_pos) | |||
5744 | ___device_tty *self;(___device_tty *self, int dir, int pos, int *final_pos) | |||
5745 | int dir;(___device_tty *self, int dir, int pos, int *final_pos) | |||
5746 | int pos;(___device_tty *self, int dir, int pos, int *final_pos) | |||
5747 | int *final_pos;)(___device_tty *self, int dir, int pos, int *final_pos) | |||
5748 | { | |||
5749 | ___device_tty *d = self; | |||
5750 | extensible_string *edited = &d->current.hist->edited; | |||
5751 | ___Cunsigned int *buf = edited->buffer; | |||
5752 | int len = edited->length; | |||
5753 | int depth = 0; | |||
5754 | ___Cunsigned int in_string = ___UNICODE_NUL0; /* assume not inside a string */ | |||
5755 | ___Cunsigned int c; | |||
5756 | ||||
5757 | #define WORD_CHAR(x)((((x) >= 48) && ((x) <= 57)) || (((x) >= 97 ) && ((x) <= 122)) || (((x) >= 65) && ( (x) <= 90)) || ((x) > 127)) \ | |||
5758 | ((((x) >= ___UNICODE_048) && ((x) <= ___UNICODE_957)) || \ | |||
5759 | (((x) >= ___UNICODE_LOWER_A97) && ((x) <= ___UNICODE_LOWER_Z122)) || \ | |||
5760 | (((x) >= ___UNICODE_UPPER_A65) && ((x) <= ___UNICODE_UPPER_Z90)) || \ | |||
5761 | ((x) > ___UNICODE_RUBOUT127)) | |||
5762 | ||||
5763 | #define OPEN_PAREN(x)((x) == 40 || (x) == 91 || (x) == 123) \ | |||
5764 | ((x) == ___UNICODE_LPAREN40 || \ | |||
5765 | (x) == ___UNICODE_LBRACKET91 || \ | |||
5766 | (x) == ___UNICODE_LBRACE123) | |||
5767 | ||||
5768 | #define CLOSE_PAREN(x)((x) == 41 || (x) == 93 || (x) == 125) \ | |||
5769 | ((x) == ___UNICODE_RPAREN41 || \ | |||
5770 | (x) == ___UNICODE_RBRACKET93 || \ | |||
5771 | (x) == ___UNICODE_RBRACE125) | |||
5772 | ||||
5773 | #define STRING_DELIM(x)((x) == 34 || (x) == 124) \ | |||
5774 | ((x) == ___UNICODE_DOUBLEQUOTE34 || (x) == ___UNICODE_VBAR124) | |||
5775 | ||||
5776 | #define INT_VECTOR(x)((x) == 115 || (x) == 83 || (x) == 117 || (x) == 85) \ | |||
5777 | ((x) == ___UNICODE_LOWER_S115 || (x) == ___UNICODE_UPPER_S83 || \ | |||
5778 | (x) == ___UNICODE_LOWER_U117 || (x) == ___UNICODE_UPPER_U85) | |||
5779 | ||||
5780 | #define FLOAT_VECTOR(x)((x) == 102 || (x) == 70) \ | |||
5781 | ((x) == ___UNICODE_LOWER_F102 || (x) == ___UNICODE_UPPER_F70) | |||
5782 | ||||
5783 | if (dir == FORW_WORD0) | |||
5784 | { | |||
5785 | while (pos < len) | |||
5786 | { | |||
5787 | c = buf[pos]; | |||
5788 | if (!WORD_CHAR(c)((((c) >= 48) && ((c) <= 57)) || (((c) >= 97 ) && ((c) <= 122)) || (((c) >= 65) && ( (c) <= 90)) || ((c) > 127))) | |||
5789 | pos++; | |||
5790 | else | |||
5791 | break; | |||
5792 | } | |||
5793 | ||||
5794 | while (pos < len) | |||
5795 | { | |||
5796 | c = buf[pos]; | |||
5797 | if (WORD_CHAR(c)((((c) >= 48) && ((c) <= 57)) || (((c) >= 97 ) && ((c) <= 122)) || (((c) >= 65) && ( (c) <= 90)) || ((c) > 127))) | |||
5798 | pos++; | |||
5799 | else | |||
5800 | break; | |||
5801 | } | |||
5802 | } | |||
5803 | else if (dir == BACK_WORD1) | |||
5804 | { | |||
5805 | while (pos > 0) | |||
5806 | { | |||
5807 | c = buf[pos-1]; | |||
5808 | if (!WORD_CHAR(c)((((c) >= 48) && ((c) <= 57)) || (((c) >= 97 ) && ((c) <= 122)) || (((c) >= 65) && ( (c) <= 90)) || ((c) > 127))) | |||
5809 | pos--; | |||
5810 | else | |||
5811 | break; | |||
5812 | } | |||
5813 | ||||
5814 | while (pos > 0) | |||
5815 | { | |||
5816 | c = buf[pos-1]; | |||
5817 | if (WORD_CHAR(c)((((c) >= 48) && ((c) <= 57)) || (((c) >= 97 ) && ((c) <= 122)) || (((c) >= 65) && ( (c) <= 90)) || ((c) > 127))) | |||
5818 | pos--; | |||
5819 | else | |||
5820 | break; | |||
5821 | } | |||
5822 | } | |||
5823 | else if (dir == FORW_SEXPR2) | |||
5824 | { | |||
5825 | /* skip whitespace */ | |||
5826 | ||||
5827 | while (pos < len) | |||
5828 | { | |||
5829 | c = buf[pos]; | |||
5830 | if (c <= ___UNICODE_SPACE32) | |||
5831 | pos++; | |||
5832 | else | |||
5833 | break; | |||
5834 | } | |||
5835 | ||||
5836 | /* skip standard read-macros */ | |||
5837 | ||||
5838 | while (pos < len) | |||
5839 | { | |||
5840 | c = buf[pos]; | |||
5841 | if (c == ___UNICODE_QUOTE39) | |||
5842 | pos++; | |||
5843 | else if (c == ___UNICODE_COMMA44) | |||
5844 | { | |||
5845 | pos++; | |||
5846 | if (pos < len && buf[pos] == ___UNICODE_AT64) | |||
5847 | pos++; | |||
5848 | } | |||
5849 | else | |||
5850 | break; | |||
5851 | } | |||
5852 | ||||
5853 | if (pos == len) | |||
5854 | { | |||
5855 | depth = -1; /* force error */ | |||
5856 | goto done_forward; | |||
5857 | } | |||
5858 | ||||
5859 | /* handle head specially */ | |||
5860 | ||||
5861 | c = buf[pos++]; | |||
5862 | ||||
5863 | if (pos < len && c == ___UNICODE_SHARP35) | |||
5864 | { | |||
5865 | /* handle #\xxx, #(...), #f32(...), etc */ | |||
5866 | ||||
5867 | c = buf[pos++]; | |||
5868 | if (c == ___UNICODE_BACKSLASH92) | |||
5869 | { | |||
5870 | if (pos < len) | |||
5871 | pos++; | |||
5872 | } | |||
5873 | else if (OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123)) | |||
5874 | depth++; | |||
5875 | else | |||
5876 | { | |||
5877 | ___BOOLint f = FLOAT_VECTOR(c)((c) == 102 || (c) == 70); | |||
5878 | if (pos < len && (f || INT_VECTOR(c)((c) == 115 || (c) == 83 || (c) == 117 || (c) == 85))) | |||
5879 | { | |||
5880 | c = buf[pos++]; | |||
5881 | if ((!f && pos < len && c == ___UNICODE_856) || | |||
5882 | (pos+1 < len && | |||
5883 | ((!f && c == ___UNICODE_149 && buf[pos] == ___UNICODE_654) || | |||
5884 | (c == ___UNICODE_351 && buf[pos] == ___UNICODE_250) || | |||
5885 | (c == ___UNICODE_654 && buf[pos] == ___UNICODE_452)) && | |||
5886 | (pos++, 1))) | |||
5887 | { | |||
5888 | c = buf[pos++]; | |||
5889 | if (OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123)) | |||
5890 | depth++; | |||
5891 | else | |||
5892 | pos--; | |||
5893 | } | |||
5894 | } | |||
5895 | } | |||
5896 | } | |||
5897 | else if (OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123)) | |||
5898 | depth++; | |||
5899 | else if (CLOSE_PAREN(c)((c) == 41 || (c) == 93 || (c) == 125)) | |||
5900 | { | |||
5901 | depth = -1; /* force error */ | |||
5902 | goto done_forward; | |||
5903 | } | |||
5904 | else if (STRING_DELIM(c)((c) == 34 || (c) == 124)) | |||
5905 | in_string = c; | |||
5906 | ||||
5907 | while (pos < len) | |||
5908 | if (in_string == ___UNICODE_NUL0) | |||
5909 | { | |||
5910 | c = buf[pos]; | |||
5911 | ||||
5912 | if (c == ___UNICODE_SHARP35) | |||
5913 | { | |||
5914 | if (pos+2 < len && buf[pos+1] == ___UNICODE_BACKSLASH92) | |||
5915 | pos += 2; | |||
5916 | } | |||
5917 | else if (c <= ___UNICODE_SPACE32 || | |||
5918 | c == ___UNICODE_SEMICOLON59 || | |||
5919 | c == ___UNICODE_QUOTE39 || | |||
5920 | c == ___UNICODE_COMMA44) | |||
5921 | { | |||
5922 | if (depth == 0) | |||
5923 | break; | |||
5924 | } | |||
5925 | else if (OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123)) | |||
5926 | { | |||
5927 | if (depth == 0) | |||
5928 | break; | |||
5929 | depth++; | |||
5930 | } | |||
5931 | else if (CLOSE_PAREN(c)((c) == 41 || (c) == 93 || (c) == 125)) | |||
5932 | { | |||
5933 | if (depth == 0) | |||
5934 | break; | |||
5935 | depth--; | |||
5936 | if (depth == 0) | |||
5937 | { | |||
5938 | pos++; | |||
5939 | break; | |||
5940 | } | |||
5941 | } | |||
5942 | else if (STRING_DELIM(c)((c) == 34 || (c) == 124)) | |||
5943 | { | |||
5944 | if (depth == 0) | |||
5945 | break; | |||
5946 | in_string = c; | |||
5947 | } | |||
5948 | ||||
5949 | pos++; | |||
5950 | } | |||
5951 | else | |||
5952 | { | |||
5953 | c = buf[pos++]; | |||
5954 | ||||
5955 | if (c == ___UNICODE_BACKSLASH92) /* character is escaped */ | |||
5956 | { | |||
5957 | if (pos < len) | |||
5958 | pos++; | |||
5959 | } | |||
5960 | else if (c == in_string) /* end of string reached */ | |||
5961 | { | |||
5962 | if (depth == 0) | |||
5963 | break; | |||
5964 | in_string = ___UNICODE_NUL0; | |||
5965 | } | |||
5966 | } | |||
5967 | ||||
5968 | done_forward:; | |||
5969 | } | |||
5970 | else | |||
5971 | { | |||
5972 | /* skip whitespace */ | |||
5973 | ||||
5974 | while (pos > 0) | |||
5975 | { | |||
5976 | c = buf[pos-1]; | |||
5977 | if (c <= ___UNICODE_SPACE32) | |||
5978 | pos--; | |||
5979 | else | |||
5980 | break; | |||
5981 | } | |||
5982 | ||||
5983 | if (pos == 0) | |||
5984 | { | |||
5985 | depth = -1; /* force error */ | |||
5986 | goto done_backward; | |||
5987 | } | |||
5988 | ||||
5989 | /* handle tail specially */ | |||
5990 | ||||
5991 | c = buf[--pos]; | |||
5992 | ||||
5993 | if (pos >= 2 && | |||
5994 | buf[pos-2] == ___UNICODE_SHARP35 && | |||
5995 | buf[pos-1] == ___UNICODE_BACKSLASH92) | |||
5996 | pos -= 2; | |||
5997 | else if (OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123)) | |||
5998 | { | |||
5999 | depth = -1; /* force error */ | |||
6000 | goto done_backward; | |||
6001 | } | |||
6002 | else if (CLOSE_PAREN(c)((c) == 41 || (c) == 93 || (c) == 125)) | |||
6003 | depth++; | |||
6004 | else if (STRING_DELIM(c)((c) == 34 || (c) == 124)) | |||
6005 | in_string = c; | |||
6006 | else if (c == ___UNICODE_QUOTE39 || | |||
6007 | c == ___UNICODE_COMMA44 || | |||
6008 | (pos >= 1 && c == ___UNICODE_AT64 && buf[pos-1] == ___UNICODE_COMMA44)) | |||
6009 | { | |||
6010 | pos++; | |||
6011 | goto skip_read_macros; | |||
6012 | } | |||
6013 | ||||
6014 | while (pos > 0) | |||
6015 | if (in_string == ___UNICODE_NUL0) | |||
6016 | { | |||
6017 | c = buf[pos-1]; | |||
6018 | ||||
6019 | if (pos >= 3 && | |||
6020 | buf[pos-3] == ___UNICODE_SHARP35 && | |||
6021 | buf[pos-2] == ___UNICODE_BACKSLASH92) | |||
6022 | pos -= 2; | |||
6023 | else if (c <= ___UNICODE_SPACE32 || | |||
6024 | c == ___UNICODE_SEMICOLON59 || | |||
6025 | c == ___UNICODE_QUOTE39 || | |||
6026 | c == ___UNICODE_COMMA44) | |||
6027 | { | |||
6028 | if (depth == 0) | |||
6029 | break; | |||
6030 | } | |||
6031 | else if (pos >= 2 && | |||
6032 | c == ___UNICODE_AT64 && | |||
6033 | buf[pos-2] == ___UNICODE_COMMA44) | |||
6034 | { | |||
6035 | if (depth == 0) | |||
6036 | break; | |||
6037 | pos--; | |||
6038 | } | |||
6039 | else if (OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123)) | |||
6040 | { | |||
6041 | if (depth == 0) | |||
6042 | break; | |||
6043 | depth--; | |||
6044 | if (depth == 0) | |||
6045 | { | |||
6046 | pos--; | |||
6047 | break; | |||
6048 | } | |||
6049 | } | |||
6050 | else if (CLOSE_PAREN(c)((c) == 41 || (c) == 93 || (c) == 125)) | |||
6051 | { | |||
6052 | if (depth == 0) | |||
6053 | break; | |||
6054 | depth++; | |||
6055 | } | |||
6056 | else if (STRING_DELIM(c)((c) == 34 || (c) == 124)) | |||
6057 | { | |||
6058 | if (depth == 0) | |||
6059 | break; | |||
6060 | in_string = c; | |||
6061 | } | |||
6062 | ||||
6063 | pos--; | |||
6064 | } | |||
6065 | else | |||
6066 | { | |||
6067 | int i; | |||
6068 | ||||
6069 | i = --pos; | |||
6070 | ||||
6071 | while (i > 0 && | |||
6072 | buf[i-1] == ___UNICODE_BACKSLASH92) /* find nb of backslashes */ | |||
6073 | i--; | |||
6074 | ||||
6075 | if ((pos-i) & 1) /* character is escaped */ | |||
6076 | pos = i; | |||
6077 | else if (buf[pos] == in_string) /* beginning of string reached */ | |||
6078 | { | |||
6079 | if (depth == 0) | |||
6080 | break; | |||
6081 | in_string = ___UNICODE_NUL0; | |||
6082 | } | |||
6083 | } | |||
6084 | ||||
6085 | done_backward:; | |||
6086 | ||||
6087 | if (dir == BACK_SEXPR3) | |||
6088 | { | |||
6089 | /* handle #(...), #f32(...), etc */ | |||
6090 | ||||
6091 | if (pos < len) | |||
6092 | { | |||
6093 | c = buf[pos]; | |||
6094 | if (OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123)) | |||
6095 | { | |||
6096 | if (pos >= 1 && buf[pos-1] == ___UNICODE_SHARP35) | |||
6097 | pos--; | |||
6098 | else if (pos >= 3 && buf[pos-3] == ___UNICODE_SHARP35) | |||
6099 | { | |||
6100 | c = buf[pos-2]; | |||
6101 | if (INT_VECTOR(c)((c) == 115 || (c) == 83 || (c) == 117 || (c) == 85) && buf[pos-1] == ___UNICODE_856) | |||
6102 | pos -= 3; | |||
6103 | } | |||
6104 | else if (pos >= 4 && buf[pos-4] == ___UNICODE_SHARP35) | |||
6105 | { | |||
6106 | ___BOOLint f; | |||
6107 | c = buf[pos-3]; | |||
6108 | f = FLOAT_VECTOR(c)((c) == 102 || (c) == 70); | |||
6109 | if (f || INT_VECTOR(c)((c) == 115 || (c) == 83 || (c) == 117 || (c) == 85)) | |||
6110 | { | |||
6111 | c = buf[pos-2]; | |||
6112 | if ((!f && | |||
6113 | c == ___UNICODE_149 && | |||
6114 | buf[pos-1] == ___UNICODE_654) || | |||
6115 | (c == ___UNICODE_351 && buf[pos-1] == ___UNICODE_250) || | |||
6116 | (c == ___UNICODE_654 && buf[pos-1] == ___UNICODE_452)) | |||
6117 | pos -= 4; | |||
6118 | } | |||
6119 | } | |||
6120 | } | |||
6121 | } | |||
6122 | ||||
6123 | /* skip standard read-macros */ | |||
6124 | ||||
6125 | skip_read_macros: | |||
6126 | ||||
6127 | while (pos > 0) | |||
6128 | { | |||
6129 | c = buf[pos-1]; | |||
6130 | if (c == ___UNICODE_QUOTE39 || c == ___UNICODE_COMMA44) | |||
6131 | pos--; | |||
6132 | else if (pos >= 2 && | |||
6133 | c == ___UNICODE_AT64 && | |||
6134 | buf[pos-2] == ___UNICODE_COMMA44) | |||
6135 | pos -= 2; | |||
6136 | else | |||
6137 | break; | |||
6138 | } | |||
6139 | } | |||
6140 | } | |||
6141 | ||||
6142 | *final_pos = pos; | |||
6143 | ||||
6144 | return (depth == 0 && in_string == ___UNICODE_NUL0); | |||
6145 | } | |||
6146 | ||||
6147 | ||||
6148 | ___HIDDENstatic ___SCMOBJlong lineeditor_delete_then_insert_chars | |||
6149 | ___P((___device_tty *self,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6150 | int pos,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6151 | ___BOOL copy_to_clipboard,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6152 | ___C *buf,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6153 | int len),(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6154 | (self,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6155 | pos,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6156 | copy_to_clipboard,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6157 | buf,(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6158 | len)(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6159 | ___device_tty *self;(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6160 | int pos;(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6161 | ___BOOL copy_to_clipboard;(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6162 | ___C *buf;(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6163 | int len;)(___device_tty *self, int pos, int copy_to_clipboard, unsigned int *buf, int len) | |||
6164 | { | |||
6165 | ___device_tty *d = self; | |||
6166 | ___SCMOBJlong e; | |||
6167 | extensible_string *edited = &d->current.hist->edited; | |||
6168 | int edit_point; | |||
6169 | int end; | |||
6170 | int n; | |||
6171 | int open_paren_point; | |||
6172 | ___Cunsigned int c; | |||
6173 | ||||
6174 | if (pos < 0 || | |||
6175 | pos > edited->length || | |||
6176 | len < 0) | |||
6177 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6178 | ||||
6179 | if (pos < d->current.edit_point) | |||
6180 | { | |||
6181 | edit_point = pos; | |||
6182 | end = d->current.edit_point; | |||
6183 | } | |||
6184 | else | |||
6185 | { | |||
6186 | edit_point = d->current.edit_point; | |||
6187 | end = pos; | |||
6188 | } | |||
6189 | ||||
6190 | n = end - edit_point; /* number of characters to delete */ | |||
6191 | ||||
6192 | if (n > 0) | |||
6193 | { | |||
6194 | if (copy_to_clipboard && | |||
6195 | ((e = lineeditor_copy_to_clipboard | |||
6196 | (d, | |||
6197 | &edited->buffer[edit_point], | |||
6198 | n)) | |||
6199 | != ___FIX(___NO_ERR)(((long)(0))<<2))) | |||
6200 | return e; | |||
6201 | ||||
6202 | extensible_string_delete (edited, edit_point, n); | |||
6203 | } | |||
6204 | ||||
6205 | if ((e = extensible_string_insert (edited, edit_point, len, buf)) | |||
6206 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6207 | return e; | |||
6208 | ||||
6209 | if (d->current.mark_point >= end) | |||
6210 | d->current.mark_point += len - n; | |||
6211 | else if (d->current.mark_point >= edit_point+len) | |||
6212 | d->current.mark_point = edit_point+len; | |||
6213 | ||||
6214 | if ((e = lineeditor_update_region | |||
6215 | (d, | |||
6216 | edit_point, | |||
6217 | (len > n) ? edited->length : edited->length - len + n)) | |||
6218 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6219 | return e; | |||
6220 | ||||
6221 | edit_point += len; | |||
6222 | ||||
6223 | if (len > 0 && | |||
6224 | d->paren_balance_duration_nsecs > 0 && | |||
6225 | !lineeditor_read_ready (d) && | |||
6226 | (c = buf[len-1], CLOSE_PAREN(c)((c) == 41 || (c) == 93 || (c) == 125)) && | |||
6227 | lineeditor_word_boundary (d, BACK_SEXPR_PAREN4, edit_point, &open_paren_point) && | |||
6228 | (c = edited->buffer[open_paren_point], OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123))) | |||
6229 | { | |||
6230 | if ((e = lineeditor_move_edit_point (d, open_paren_point)) | |||
6231 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6232 | { | |||
6233 | lineeditor_output_drain (d); /* ignore error */ | |||
6234 | ||||
6235 | d->current.edit_point = edit_point; | |||
6236 | d->current.completion_point = edit_point; | |||
6237 | d->current.paren_balance_trigger = 1; | |||
6238 | } | |||
6239 | } | |||
6240 | else | |||
6241 | e = lineeditor_move_edit_point (d, edit_point); | |||
6242 | ||||
6243 | return e; | |||
6244 | } | |||
6245 | ||||
6246 | ||||
6247 | ___HIDDENstatic ___SCMOBJlong lineeditor_insert_chars | |||
6248 | ___P((___device_tty *self,(___device_tty *self, unsigned int *buf, int len) | |||
6249 | ___C *buf,(___device_tty *self, unsigned int *buf, int len) | |||
6250 | int len),(___device_tty *self, unsigned int *buf, int len) | |||
6251 | (self,(___device_tty *self, unsigned int *buf, int len) | |||
6252 | buf,(___device_tty *self, unsigned int *buf, int len) | |||
6253 | len)(___device_tty *self, unsigned int *buf, int len) | |||
6254 | ___device_tty *self;(___device_tty *self, unsigned int *buf, int len) | |||
6255 | ___C *buf;(___device_tty *self, unsigned int *buf, int len) | |||
6256 | int len;)(___device_tty *self, unsigned int *buf, int len) | |||
6257 | { | |||
6258 | ___device_tty *d = self; | |||
6259 | ||||
6260 | #if 1 | |||
6261 | ||||
6262 | if (len > 0) | |||
6263 | return lineeditor_delete_then_insert_chars | |||
6264 | (d, | |||
6265 | d->current.edit_point, | |||
6266 | 0, | |||
6267 | buf, | |||
6268 | len); | |||
6269 | ||||
6270 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6271 | ||||
6272 | #else | |||
6273 | ||||
6274 | ___SCMOBJlong e; | |||
6275 | extensible_string *edited = &d->current.hist->edited; | |||
6276 | int edit_point = d->current.edit_point; | |||
6277 | int open_paren_point; | |||
6278 | ___Cunsigned int c; | |||
6279 | ||||
6280 | if (len <= 0) | |||
6281 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6282 | ||||
6283 | if ((e = extensible_string_insert (edited, edit_point, len, buf)) | |||
6284 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6285 | return e; | |||
6286 | ||||
6287 | if (d->current.mark_point > edit_point) | |||
6288 | d->current.mark_point += len; | |||
6289 | ||||
6290 | if ((e = lineeditor_update_region (d, edit_point, edited->length)) | |||
6291 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6292 | return e; | |||
6293 | ||||
6294 | edit_point += len; | |||
6295 | ||||
6296 | if (d->paren_balance_duration_nsecs > 0 && | |||
6297 | !lineeditor_read_ready (d) && | |||
6298 | (c = buf[len-1], CLOSE_PAREN(c)((c) == 41 || (c) == 93 || (c) == 125)) && | |||
6299 | lineeditor_word_boundary (d, BACK_SEXPR_PAREN4, edit_point, &open_paren_point) && | |||
6300 | (c = edited->buffer[open_paren_point], OPEN_PAREN(c)((c) == 40 || (c) == 91 || (c) == 123))) | |||
6301 | { | |||
6302 | if ((e = lineeditor_move_edit_point (d, open_paren_point)) | |||
6303 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6304 | return e; | |||
6305 | ||||
6306 | lineeditor_output_drain (d); /* ignore error */ | |||
6307 | ||||
6308 | d->current.edit_point = edit_point; | |||
6309 | d->current.completion_point = edit_point; | |||
6310 | d->current.paren_balance_trigger = 1; | |||
6311 | ||||
6312 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6313 | } | |||
6314 | ||||
6315 | return lineeditor_move_edit_point (d, edit_point); | |||
6316 | #endif | |||
6317 | } | |||
6318 | ||||
6319 | ||||
6320 | ___HIDDENstatic ___SCMOBJlong lineeditor_delete_chars | |||
6321 | ___P((___device_tty *self,(___device_tty *self, int pos, int copy_to_clipboard) | |||
6322 | int pos,(___device_tty *self, int pos, int copy_to_clipboard) | |||
6323 | ___BOOL copy_to_clipboard),(___device_tty *self, int pos, int copy_to_clipboard) | |||
6324 | (self,(___device_tty *self, int pos, int copy_to_clipboard) | |||
6325 | pos,(___device_tty *self, int pos, int copy_to_clipboard) | |||
6326 | copy_to_clipboard)(___device_tty *self, int pos, int copy_to_clipboard) | |||
6327 | ___device_tty *self;(___device_tty *self, int pos, int copy_to_clipboard) | |||
6328 | int pos;(___device_tty *self, int pos, int copy_to_clipboard) | |||
6329 | ___BOOL copy_to_clipboard;)(___device_tty *self, int pos, int copy_to_clipboard) | |||
6330 | { | |||
6331 | ___device_tty *d = self; | |||
6332 | ||||
6333 | #if 1 | |||
6334 | ||||
6335 | return lineeditor_delete_then_insert_chars | |||
6336 | (d, | |||
6337 | pos, | |||
6338 | copy_to_clipboard, | |||
6339 | NULL((void*)0), | |||
6340 | 0); | |||
6341 | ||||
6342 | #else | |||
6343 | ||||
6344 | ___SCMOBJlong e; | |||
6345 | extensible_string *edited = &d->current.hist->edited; | |||
6346 | int start; | |||
6347 | int end; | |||
6348 | int n; | |||
6349 | ||||
6350 | if (pos < 0 || | |||
6351 | pos > edited->length) | |||
6352 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6353 | ||||
6354 | if (pos < d->current.edit_point) | |||
6355 | { | |||
6356 | start = pos; | |||
6357 | end = d->current.edit_point; | |||
6358 | } | |||
6359 | else | |||
6360 | { | |||
6361 | start = d->current.edit_point; | |||
6362 | end = pos; | |||
6363 | } | |||
6364 | ||||
6365 | n = end - start; | |||
6366 | ||||
6367 | if (n == 0) | |||
6368 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6369 | ||||
6370 | if (copy_to_clipboard && | |||
6371 | ((e = lineeditor_copy_to_clipboard (d, &edited->buffer[start], n)) | |||
6372 | != ___FIX(___NO_ERR)(((long)(0))<<2))) | |||
6373 | return e; | |||
6374 | ||||
6375 | extensible_string_delete (edited, start, n); | |||
6376 | ||||
6377 | if (d->current.mark_point >= start) | |||
6378 | { | |||
6379 | if (d->current.mark_point >= end) | |||
6380 | d->current.mark_point -= n; | |||
6381 | else | |||
6382 | d->current.mark_point = start; | |||
6383 | } | |||
6384 | ||||
6385 | if ((e = lineeditor_update_region (d, start, edited->length + n)) | |||
6386 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6387 | return e; | |||
6388 | ||||
6389 | return lineeditor_move_edit_point (d, start); | |||
6390 | #endif | |||
6391 | } | |||
6392 | ||||
6393 | ||||
6394 | ___HIDDENstatic void lineeditor_rotate_left_chars | |||
6395 | ___P((___device_tty *self,(___device_tty *self, int start, int end, int n) | |||
6396 | int start,(___device_tty *self, int start, int end, int n) | |||
6397 | int end,(___device_tty *self, int start, int end, int n) | |||
6398 | int n),(___device_tty *self, int start, int end, int n) | |||
6399 | (self,(___device_tty *self, int start, int end, int n) | |||
6400 | start,(___device_tty *self, int start, int end, int n) | |||
6401 | end,(___device_tty *self, int start, int end, int n) | |||
6402 | n)(___device_tty *self, int start, int end, int n) | |||
6403 | ___device_tty *self;(___device_tty *self, int start, int end, int n) | |||
6404 | int start;(___device_tty *self, int start, int end, int n) | |||
6405 | int end;(___device_tty *self, int start, int end, int n) | |||
6406 | int n;)(___device_tty *self, int start, int end, int n) | |||
6407 | { | |||
6408 | ___device_tty *d = self; | |||
6409 | extensible_string *edited = &d->current.hist->edited; | |||
6410 | ___Cunsigned int *p = &edited->buffer[start]; | |||
6411 | ___Cunsigned int temp; | |||
6412 | int len = end-start; | |||
6413 | int left = len; | |||
6414 | int i; | |||
6415 | int j; | |||
6416 | int k; | |||
6417 | ||||
6418 | i = 0; | |||
6419 | while (left > 0) | |||
6420 | { | |||
6421 | temp = p[i]; | |||
6422 | j = i; | |||
6423 | k = (j+n) % len; | |||
6424 | left--; | |||
6425 | while (k != i) | |||
6426 | { | |||
6427 | p[j] = p[k]; | |||
6428 | j = k; | |||
6429 | k = (j+n) % len; | |||
6430 | left--; | |||
6431 | } | |||
6432 | p[j] = temp; | |||
6433 | i++; | |||
6434 | } | |||
6435 | } | |||
6436 | ||||
6437 | ||||
6438 | ___HIDDENstatic ___SCMOBJlong lineeditor_transpose_chars | |||
6439 | ___P((___device_tty *self,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6440 | int start1,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6441 | int end1,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6442 | int start2,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6443 | int end2),(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6444 | (self,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6445 | start1,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6446 | end1,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6447 | start2,(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6448 | end2)(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6449 | ___device_tty *self;(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6450 | int start1;(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6451 | int end1;(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6452 | int start2;(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6453 | int end2;)(___device_tty *self, int start1, int end1, int start2, int end2 ) | |||
6454 | { | |||
6455 | ___device_tty *d = self; | |||
6456 | ___SCMOBJlong e; | |||
6457 | ||||
6458 | if (start1 > end1 || | |||
6459 | end1 > start2 || | |||
6460 | start2 > end2) | |||
6461 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6462 | ||||
6463 | lineeditor_rotate_left_chars | |||
6464 | (d, | |||
6465 | start1, | |||
6466 | end2, | |||
6467 | end1-start1); | |||
6468 | ||||
6469 | lineeditor_rotate_left_chars | |||
6470 | (d, | |||
6471 | start1, | |||
6472 | end2-(end1-start1), | |||
6473 | start2-end1); | |||
6474 | ||||
6475 | if ((e = lineeditor_update_region (d, start1, end2)) | |||
6476 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6477 | return e; | |||
6478 | ||||
6479 | return lineeditor_move_edit_point (d, end2); | |||
6480 | } | |||
6481 | ||||
6482 | ||||
6483 | typedef struct | |||
6484 | { | |||
6485 | extensible_string *buf; | |||
6486 | int word_start; | |||
6487 | int completion_point; | |||
6488 | int word_end; | |||
6489 | ___SCMOBJlong next; | |||
6490 | int common_length; | |||
6491 | } visit_symbol_data; | |||
6492 | ||||
6493 | ||||
6494 | ___HIDDENstatic void visit_symbol | |||
6495 | ___P((___SCMOBJ sym,(long sym, void *data) | |||
6496 | void *data),(long sym, void *data) | |||
6497 | (sym,(long sym, void *data) | |||
6498 | data)(long sym, void *data) | |||
6499 | ___SCMOBJ sym;(long sym, void *data) | |||
6500 | void *data;)(long sym, void *data) | |||
6501 | { | |||
6502 | visit_symbol_data *dat = ___CAST(visit_symbol_data*,data)((visit_symbol_data*)(data)); | |||
6503 | ___SCMOBJlong name = ___FIELD(sym,___SYMKEY_NAME)(*((((long*)((sym)-(1)))+1)+0)); | |||
6504 | int n = ___INT(___STRINGLENGTH(name))(((((long)(((((unsigned long)((*((long*)((name)-(1))))))>> (3 +5))>>2)))<<2))>>2); | |||
6505 | int word_start = dat->word_start; | |||
6506 | int prefix = dat->completion_point - word_start; | |||
6507 | int len = dat->word_end - word_start; | |||
6508 | int i = 0; | |||
6509 | ||||
6510 | if (n <= prefix) | |||
6511 | return; | |||
6512 | ||||
6513 | for (i=0; i<prefix; i++) | |||
6514 | { | |||
6515 | ___Cunsigned int c1 = ___INT(___STRINGREF(name,___FIX(i)))((((((long)(((unsigned int)(*(((unsigned int*)((((long*)((name )-(1)))+1)))+(((((long)(i))<<2))>>2))))))<< 2)+2))>>2); | |||
6516 | ___Cunsigned int c2 = dat->buf->buffer[word_start+i]; | |||
6517 | if (c1 != c2) | |||
6518 | return; | |||
6519 | } | |||
6520 | ||||
6521 | while (i < n) | |||
6522 | { | |||
6523 | if (i < len) | |||
6524 | { | |||
6525 | ___Cunsigned int c1 = ___INT(___STRINGREF(name,___FIX(i)))((((((long)(((unsigned int)(*(((unsigned int*)((((long*)((name )-(1)))+1)))+(((((long)(i))<<2))>>2))))))<< 2)+2))>>2); | |||
6526 | ___Cunsigned int c2 = dat->buf->buffer[word_start+i]; | |||
6527 | if (c1 < c2) | |||
6528 | return; | |||
6529 | if (c1 > c2) | |||
6530 | goto found; | |||
6531 | } | |||
6532 | else | |||
6533 | goto found; | |||
6534 | i++; | |||
6535 | } | |||
6536 | ||||
6537 | return; | |||
6538 | ||||
6539 | found: | |||
6540 | ||||
6541 | if (dat->next == ___FAL((((long)(-1))<<2)+2)) | |||
6542 | { | |||
6543 | dat->next = sym; | |||
6544 | dat->common_length = n; | |||
6545 | } | |||
6546 | else | |||
6547 | { | |||
6548 | ___SCMOBJlong name2 = ___FIELD(dat->next,___SYMKEY_NAME)(*((((long*)((dat->next)-(1)))+1)+0)); | |||
6549 | int n2 = ___INT(___STRINGLENGTH(name2))(((((long)(((((unsigned long)((*((long*)((name2)-(1))))))>> (3 +5))>>2)))<<2))>>2); | |||
6550 | i = 0; | |||
6551 | while (i < n) | |||
6552 | { | |||
6553 | if (i < n2) | |||
6554 | { | |||
6555 | ___Cunsigned int c1 = ___INT(___STRINGREF(name,___FIX(i)))((((((long)(((unsigned int)(*(((unsigned int*)((((long*)((name )-(1)))+1)))+(((((long)(i))<<2))>>2))))))<< 2)+2))>>2); | |||
6556 | ___Cunsigned int c2 = ___INT(___STRINGREF(name2,___FIX(i)))((((((long)(((unsigned int)(*(((unsigned int*)((((long*)((name2 )-(1)))+1)))+(((((long)(i))<<2))>>2))))))<< 2)+2))>>2); | |||
6557 | if (c1 < c2) | |||
6558 | goto found2; | |||
6559 | if (c1 > c2) | |||
6560 | goto done; | |||
6561 | } | |||
6562 | else | |||
6563 | goto done; | |||
6564 | i++; | |||
6565 | } | |||
6566 | found2: | |||
6567 | dat->next = sym; | |||
6568 | done: | |||
6569 | dat->common_length = i; | |||
6570 | } | |||
6571 | } | |||
6572 | ||||
6573 | ||||
6574 | ___HIDDENstatic int complete_word | |||
6575 | ___P((extensible_string *buf,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6576 | int word_start,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6577 | int completion_point,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6578 | int word_end,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6579 | extensible_string *completion),(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6580 | (buf,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6581 | word_start,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6582 | completion_point,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6583 | word_end,(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6584 | completion)(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6585 | extensible_string *buf;(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6586 | int word_start;(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6587 | int completion_point;(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6588 | int word_end;(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6589 | extensible_string *completion;)(extensible_string *buf, int word_start, int completion_point , int word_end, extensible_string *completion) | |||
6590 | { | |||
6591 | #define FOUND_COMPLETION0 0 | |||
6592 | #define NO_COMPLETION1 1 | |||
6593 | #define CANNOT_COMPLETE2 2 | |||
6594 | ||||
6595 | visit_symbol_data dat; | |||
6596 | ||||
6597 | if (completion_point <= word_start) | |||
6598 | return NO_COMPLETION1; | |||
6599 | ||||
6600 | dat.buf = buf; | |||
6601 | dat.word_start = word_start; | |||
6602 | dat.completion_point = completion_point; | |||
6603 | dat.word_end = word_end; | |||
6604 | dat.next = ___FAL((((long)(-1))<<2)+2); | |||
6605 | dat.common_length = 0; | |||
6606 | ||||
6607 | ___for_each_symkey (___sSYMBOL8, visit_symbol, ___CAST(void*,&dat)((void*)(&dat))); | |||
6608 | ||||
6609 | if (dat.next != ___FAL((((long)(-1))<<2)+2)) | |||
6610 | { | |||
6611 | ___SCMOBJlong name = ___FIELD(dat.next,___SYMKEY_NAME)(*((((long*)((dat.next)-(1)))+1)+0)); | |||
6612 | int n = ___INT(___STRINGLENGTH(name))(((((long)(((((unsigned long)((*((long*)((name)-(1))))))>> (3 +5))>>2)))<<2))>>2); | |||
6613 | int i; | |||
6614 | ||||
6615 | #define USE_EMACS_COMPLETION | |||
6616 | ||||
6617 | #ifdef USE_EMACS_COMPLETION | |||
6618 | if (dat.common_length > word_end - word_start) | |||
6619 | n = dat.common_length; | |||
6620 | #endif | |||
6621 | ||||
6622 | if (extensible_string_setup (completion, n) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6623 | return CANNOT_COMPLETE2; | |||
6624 | ||||
6625 | for (i=0; i<n; i++) | |||
6626 | { | |||
6627 | ___Cunsigned int c = ___INT(___STRINGREF(name,___FIX(i)))((((((long)(((unsigned int)(*(((unsigned int*)((((long*)((name )-(1)))+1)))+(((((long)(i))<<2))>>2))))))<< 2)+2))>>2); | |||
6628 | if (extensible_string_insert_at_end (completion, 1, &c) | |||
6629 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6630 | { | |||
6631 | extensible_string_cleanup (completion); | |||
6632 | return CANNOT_COMPLETE2; | |||
6633 | } | |||
6634 | } | |||
6635 | return FOUND_COMPLETION0; | |||
6636 | } | |||
6637 | ||||
6638 | return NO_COMPLETION1; | |||
6639 | } | |||
6640 | ||||
6641 | ||||
6642 | ___HIDDENstatic ___SCMOBJlong lineeditor_word_completion | |||
6643 | ___P((___device_tty *self),(___device_tty *self) | |||
6644 | (self)(___device_tty *self) | |||
6645 | ___device_tty *self;)(___device_tty *self) | |||
6646 | { | |||
6647 | /* | |||
6648 | * Complete current word. | |||
6649 | */ | |||
6650 | ||||
6651 | ___device_tty *d = self; | |||
6652 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6653 | int word_start; | |||
6654 | int completion_point; | |||
6655 | extensible_string completion; | |||
6656 | ||||
6657 | completion_point = d->current.completion_point; | |||
6658 | ||||
6659 | if (!lineeditor_word_boundary (d, BACK_SEXPR_PAREN4, completion_point, &word_start)) | |||
6660 | word_start = completion_point; | |||
6661 | ||||
6662 | switch (complete_word (&d->current.hist->edited, | |||
6663 | word_start, | |||
6664 | completion_point, | |||
6665 | d->current.edit_point, | |||
6666 | &completion)) | |||
6667 | { | |||
6668 | case FOUND_COMPLETION0: | |||
6669 | e = lineeditor_delete_then_insert_chars | |||
6670 | (d, | |||
6671 | word_start, | |||
6672 | 0, | |||
6673 | completion.buffer, | |||
6674 | completion.length); | |||
6675 | extensible_string_cleanup (&completion); | |||
6676 | break; | |||
6677 | ||||
6678 | case NO_COMPLETION1: | |||
6679 | if ((e = lineeditor_delete_then_insert_chars | |||
6680 | (d, | |||
6681 | completion_point, | |||
6682 | 0, | |||
6683 | NULL((void*)0), | |||
6684 | 0)) | |||
6685 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6686 | e = lineeditor_output_char_repetition | |||
6687 | (d, | |||
6688 | ___UNICODE_BELL7, | |||
6689 | 1, | |||
6690 | d->output_attrs); | |||
6691 | break; | |||
6692 | ||||
6693 | case CANNOT_COMPLETE2: | |||
6694 | default: | |||
6695 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6696 | } | |||
6697 | ||||
6698 | d->current.completion_point = completion_point; | |||
6699 | ||||
6700 | return e; | |||
6701 | } | |||
6702 | ||||
6703 | ||||
6704 | ___HIDDENstatic ___SCMOBJlong lineeditor_move_history | |||
6705 | ___P((___device_tty *self,(___device_tty *self, lineeditor_history *h) | |||
6706 | lineeditor_history *h),(___device_tty *self, lineeditor_history *h) | |||
6707 | (self,(___device_tty *self, lineeditor_history *h) | |||
6708 | h)(___device_tty *self, lineeditor_history *h) | |||
6709 | ___device_tty *self;(___device_tty *self, lineeditor_history *h) | |||
6710 | lineeditor_history *h;)(___device_tty *self, lineeditor_history *h) | |||
6711 | { | |||
6712 | ___device_tty *d = self; | |||
6713 | ___SCMOBJlong e; | |||
6714 | int old_length; | |||
6715 | int new_length; | |||
6716 | ||||
6717 | if ((e = lineeditor_history_begin_edit (d, h)) | |||
6718 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6719 | return e; | |||
6720 | ||||
6721 | if ((e = lineeditor_move_edit_point (d, 0)) | |||
6722 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6723 | return e; | |||
6724 | ||||
6725 | old_length = d->current.hist->edited.length; | |||
6726 | new_length = h->edited.length; | |||
6727 | ||||
6728 | d->current.mark_point = 0; | |||
6729 | d->current.hist = h; | |||
6730 | ||||
6731 | if ((e = lineeditor_update_region | |||
6732 | (d, | |||
6733 | 0, | |||
6734 | (new_length > old_length) ? new_length : old_length)) | |||
6735 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6736 | return e; | |||
6737 | ||||
6738 | return lineeditor_move_edit_point (d, new_length); | |||
6739 | } | |||
6740 | ||||
6741 | ||||
6742 | ___HIDDENstatic ___SCMOBJlong lineeditor_move_history_relative | |||
6743 | ___P((___device_tty *self,(___device_tty *self, int back) | |||
6744 | ___BOOL back),(___device_tty *self, int back) | |||
6745 | (self,(___device_tty *self, int back) | |||
6746 | back)(___device_tty *self, int back) | |||
6747 | ___device_tty *self;(___device_tty *self, int back) | |||
6748 | ___BOOL back;)(___device_tty *self, int back) | |||
6749 | { | |||
6750 | ___device_tty *d = self; | |||
6751 | lineeditor_history *h; | |||
6752 | lineeditor_history *limit; | |||
6753 | ||||
6754 | if (back) | |||
6755 | { | |||
6756 | h = d->current.hist->prev; | |||
6757 | limit = d->hist_last; | |||
6758 | } | |||
6759 | else | |||
6760 | { | |||
6761 | h = d->current.hist->next; | |||
6762 | limit = d->hist_last->next; | |||
6763 | } | |||
6764 | ||||
6765 | if (h == limit) | |||
6766 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6767 | ||||
6768 | return lineeditor_move_history (d, h); | |||
6769 | } | |||
6770 | ||||
6771 | ||||
6772 | ___HIDDENstatic ___SCMOBJlong lineeditor_line_done | |||
6773 | ___P((___device_tty *self,(___device_tty *self, int end_of_file) | |||
6774 | ___BOOL end_of_file),(___device_tty *self, int end_of_file) | |||
6775 | (self,(___device_tty *self, int end_of_file) | |||
6776 | end_of_file)(___device_tty *self, int end_of_file) | |||
6777 | ___device_tty *self;(___device_tty *self, int end_of_file) | |||
6778 | ___BOOL end_of_file;)(___device_tty *self, int end_of_file) | |||
6779 | { | |||
6780 | ___device_tty *d = self; | |||
6781 | ___SCMOBJlong e; | |||
6782 | extensible_string *edited = &d->current.hist->edited; | |||
6783 | extensible_string *input_line = &d->input_line; | |||
6784 | ||||
6785 | /* | |||
6786 | * Transfer the current edited line to the input. | |||
6787 | */ | |||
6788 | ||||
6789 | if (input_line->buffer == NULL((void*)0)) | |||
6790 | { | |||
6791 | d->input_line_lo = 0; | |||
6792 | ||||
6793 | if ((e = extensible_string_copy | |||
6794 | (edited->buffer, | |||
6795 | edited->length, | |||
6796 | input_line, | |||
6797 | 1)) | |||
6798 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6799 | return e; | |||
6800 | ||||
6801 | if (!end_of_file) | |||
6802 | { | |||
6803 | int old_length = input_line->length; | |||
6804 | if ((e = extensible_string_set_length (input_line, old_length+1, 0)) | |||
6805 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6806 | { | |||
6807 | extensible_string_cleanup (input_line); | |||
6808 | d->input_line.buffer = NULL((void*)0); | |||
6809 | return e; | |||
6810 | } | |||
6811 | input_line->buffer[old_length] = char_EOL10; | |||
6812 | } | |||
6813 | } | |||
6814 | ||||
6815 | /* | |||
6816 | * Update history (empty lines are not added). | |||
6817 | */ | |||
6818 | ||||
6819 | if (edited->length == 0) | |||
6820 | { | |||
6821 | if ((e = lineeditor_move_edit_point (d, edited->length)) | |||
6822 | == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
6823 | (end_of_file || | |||
6824 | (e = lineeditor_newline (d)) | |||
6825 | == ___FIX(___NO_ERR)(((long)(0))<<2))) | |||
6826 | extensible_string_set_length | |||
6827 | (&d->hist_last->edited, | |||
6828 | 0, | |||
6829 | 1); /* ignore error */ | |||
6830 | } | |||
6831 | else | |||
6832 | { | |||
6833 | /* | |||
6834 | * Make a copy of the current edited line for the history. | |||
6835 | */ | |||
6836 | ||||
6837 | extensible_string actual; | |||
6838 | ||||
6839 | if ((e = extensible_string_copy | |||
6840 | (edited->buffer, | |||
6841 | edited->length, | |||
6842 | &actual, | |||
6843 | 0)) | |||
6844 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6845 | { | |||
6846 | /* | |||
6847 | * Add the current edited line to the history. | |||
6848 | */ | |||
6849 | ||||
6850 | lineeditor_history *next_line; | |||
6851 | ||||
6852 | if ((e = lineeditor_history_setup (d, &next_line)) | |||
6853 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6854 | { | |||
6855 | if ((e = lineeditor_history_begin_edit (d, next_line)) | |||
6856 | == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
6857 | (e = lineeditor_move_edit_point (d, edited->length)) | |||
6858 | == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
6859 | (e = lineeditor_newline (d)) | |||
6860 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6861 | { | |||
6862 | extensible_string_cleanup (&d->hist_last->actual); | |||
6863 | d->hist_last->actual = actual; | |||
6864 | lineeditor_history_add_last (d, next_line); | |||
6865 | lineeditor_history_trim (d); | |||
6866 | } | |||
6867 | else | |||
6868 | lineeditor_history_cleanup (d, next_line); /* ignore error */ | |||
6869 | } | |||
6870 | ||||
6871 | if (e != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6872 | extensible_string_cleanup (&actual); | |||
6873 | } | |||
6874 | } | |||
6875 | ||||
6876 | if (e == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
6877 | { | |||
6878 | /* | |||
6879 | * Revert history lines to their nonedited state. | |||
6880 | */ | |||
6881 | ||||
6882 | lineeditor_history *h = d->hist_last; | |||
6883 | ||||
6884 | for (;;) | |||
6885 | { | |||
6886 | h = h->prev; | |||
6887 | if (h == d->hist_last) | |||
6888 | break; | |||
6889 | lineeditor_history_end_edit (d, h); | |||
6890 | } | |||
6891 | ||||
6892 | /* | |||
6893 | * Prepare editing of next line. | |||
6894 | */ | |||
6895 | ||||
6896 | d->editing_line = 0; | |||
6897 | d->prompt_length = 0; | |||
6898 | } | |||
6899 | ||||
6900 | return e; | |||
6901 | } | |||
6902 | ||||
6903 | ||||
6904 | ___HIDDENstatic ___SCMOBJlong lineeditor_end_paren_balance | |||
6905 | ___P((___device_tty *self),(___device_tty *self) | |||
6906 | (self)(___device_tty *self) | |||
6907 | ___device_tty *self;)(___device_tty *self) | |||
6908 | { | |||
6909 | ___device_tty *d = self; | |||
6910 | ||||
6911 | if (d->current.paren_balance_in_progress) | |||
6912 | { | |||
6913 | d->current.paren_balance_in_progress = 0; | |||
6914 | if (d->editing_line) | |||
6915 | return lineeditor_move_edit_point | |||
6916 | (d, | |||
6917 | d->current.edit_point); | |||
6918 | } | |||
6919 | ||||
6920 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6921 | } | |||
6922 | ||||
6923 | ||||
6924 | ___HIDDENstatic ___SCMOBJlong lineeditor_process_single_event | |||
6925 | ___P((___device_tty *self,(___device_tty *self, lineeditor_event *ev) | |||
6926 | lineeditor_event *ev),(___device_tty *self, lineeditor_event *ev) | |||
6927 | (self,(___device_tty *self, lineeditor_event *ev) | |||
6928 | ev)(___device_tty *self, lineeditor_event *ev) | |||
6929 | ___device_tty *self;(___device_tty *self, lineeditor_event *ev) | |||
6930 | lineeditor_event *ev;)(___device_tty *self, lineeditor_event *ev) | |||
6931 | { | |||
6932 | ___device_tty *d = self; | |||
6933 | extensible_string *edited = &d->current.hist->edited; | |||
6934 | ||||
6935 | switch (ev->event_kind) | |||
6936 | { | |||
6937 | case LINEEDITOR_EV_NONE0: | |||
6938 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6939 | ||||
6940 | case LINEEDITOR_EV_KEY1: | |||
6941 | if (ev->event_char < ___UNICODE_SPACE32 || /* discard control characters */ | |||
6942 | ev->event_char == ___UNICODE_RUBOUT127) | |||
6943 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6944 | return lineeditor_insert_chars (d, &ev->event_char, 1); | |||
6945 | ||||
6946 | case LINEEDITOR_EV_RETURN2: | |||
6947 | return lineeditor_line_done (d, 0); | |||
6948 | ||||
6949 | case LINEEDITOR_EV_BACK3: | |||
6950 | return lineeditor_delete_chars (d, d->current.edit_point-1, 0); | |||
6951 | ||||
6952 | case LINEEDITOR_EV_BACK_WORD4: | |||
6953 | case LINEEDITOR_EV_BACK_SEXPR5: | |||
6954 | { | |||
6955 | int i; | |||
6956 | int dir = (ev->event_kind == LINEEDITOR_EV_BACK_WORD4) | |||
6957 | ? BACK_WORD1 | |||
6958 | : BACK_SEXPR3; | |||
6959 | if (!lineeditor_word_boundary (d, dir, d->current.edit_point, &i)) | |||
6960 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6961 | return lineeditor_delete_chars (d, i, 1); | |||
6962 | } | |||
6963 | ||||
6964 | case LINEEDITOR_EV_TAB6: | |||
6965 | return lineeditor_word_completion (d); | |||
6966 | ||||
6967 | case LINEEDITOR_EV_MARK7: | |||
6968 | d->current.mark_point = d->current.edit_point; | |||
6969 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
6970 | ||||
6971 | case LINEEDITOR_EV_PASTE8: | |||
6972 | return lineeditor_paste_from_clipboard (d); | |||
6973 | ||||
6974 | case LINEEDITOR_EV_CUT9: | |||
6975 | return lineeditor_delete_chars (d, d->current.mark_point, 1); | |||
6976 | ||||
6977 | case LINEEDITOR_EV_CUT_RIGHT10: | |||
6978 | return lineeditor_delete_chars (d, edited->length, 1); | |||
6979 | ||||
6980 | case LINEEDITOR_EV_CUT_LEFT11: | |||
6981 | return lineeditor_delete_chars (d, 0, 1); | |||
6982 | ||||
6983 | case LINEEDITOR_EV_REFRESH12: | |||
6984 | return lineeditor_refresh (d); | |||
6985 | ||||
6986 | case LINEEDITOR_EV_TRANSPOSE13: | |||
6987 | { | |||
6988 | int i = d->current.edit_point; | |||
6989 | if (i <= 0 || | |||
6990 | edited->length < 2) | |||
6991 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
6992 | if (i == edited->length) | |||
6993 | return lineeditor_transpose_chars (d, i-2, i-1, i-1, i); | |||
6994 | else | |||
6995 | return lineeditor_transpose_chars (d, i-1, i, i, i+1); | |||
6996 | } | |||
6997 | ||||
6998 | case LINEEDITOR_EV_TRANSPOSE_WORD14: | |||
6999 | case LINEEDITOR_EV_TRANSPOSE_SEXPR15: | |||
7000 | { | |||
7001 | int start1; | |||
7002 | int end1; | |||
7003 | int start2; | |||
7004 | int end2; | |||
7005 | int dir = (ev->event_kind == LINEEDITOR_EV_TRANSPOSE_WORD14) | |||
7006 | ? FORW_WORD0 | |||
7007 | : FORW_SEXPR2; | |||
7008 | if (!lineeditor_word_boundary (d, dir, d->current.edit_point, &end2) || | |||
7009 | !lineeditor_word_boundary (d, dir+1, end2, &start2) || | |||
7010 | !lineeditor_word_boundary (d, dir+1, start2, &start1) || | |||
7011 | !lineeditor_word_boundary (d, dir, start1, &end1)) | |||
7012 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
7013 | return lineeditor_transpose_chars (d, start1, end1, start2, end2); | |||
7014 | } | |||
7015 | ||||
7016 | case LINEEDITOR_EV_UP16: | |||
7017 | return lineeditor_move_history_relative (d, 1); | |||
7018 | ||||
7019 | case LINEEDITOR_EV_DOWN17: | |||
7020 | return lineeditor_move_history_relative (d, 0); | |||
7021 | ||||
7022 | case LINEEDITOR_EV_RIGHT18: | |||
7023 | return lineeditor_move_edit_point (d, d->current.edit_point+1); | |||
7024 | ||||
7025 | case LINEEDITOR_EV_RIGHT_WORD19: | |||
7026 | case LINEEDITOR_EV_RIGHT_SEXPR20: | |||
7027 | { | |||
7028 | int i; | |||
7029 | int dir = (ev->event_kind == LINEEDITOR_EV_RIGHT_WORD19) | |||
7030 | ? FORW_WORD0 | |||
7031 | : FORW_SEXPR2; | |||
7032 | lineeditor_word_boundary (d, dir, d->current.edit_point, &i); | |||
7033 | return lineeditor_move_edit_point (d, i); | |||
7034 | } | |||
7035 | ||||
7036 | case LINEEDITOR_EV_LEFT21: | |||
7037 | return lineeditor_move_edit_point (d, d->current.edit_point-1); | |||
7038 | ||||
7039 | case LINEEDITOR_EV_LEFT_WORD22: | |||
7040 | case LINEEDITOR_EV_LEFT_SEXPR23: | |||
7041 | { | |||
7042 | int i; | |||
7043 | int dir = (ev->event_kind == LINEEDITOR_EV_LEFT_WORD22) | |||
7044 | ? BACK_WORD1 | |||
7045 | : BACK_SEXPR3; | |||
7046 | lineeditor_word_boundary (d, dir, d->current.edit_point, &i); | |||
7047 | return lineeditor_move_edit_point (d, i); | |||
7048 | } | |||
7049 | ||||
7050 | case LINEEDITOR_EV_HOME24: | |||
7051 | return lineeditor_move_edit_point (d, 0); | |||
7052 | ||||
7053 | case LINEEDITOR_EV_HOME_DOC25: | |||
7054 | return lineeditor_move_history (d, d->hist_last->next); | |||
7055 | ||||
7056 | case LINEEDITOR_EV_INSERT26: | |||
7057 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
7058 | ||||
7059 | case LINEEDITOR_EV_DELETE27: | |||
7060 | if (edited->length == 0) | |||
7061 | return lineeditor_line_done (d, 1); | |||
7062 | else | |||
7063 | return lineeditor_delete_chars (d, d->current.edit_point+1, 0); | |||
7064 | ||||
7065 | case LINEEDITOR_EV_DELETE_WORD28: | |||
7066 | case LINEEDITOR_EV_DELETE_SEXPR29: | |||
7067 | { | |||
7068 | int i; | |||
7069 | int dir = (ev->event_kind == LINEEDITOR_EV_DELETE_WORD28) | |||
7070 | ? FORW_WORD0 | |||
7071 | : FORW_SEXPR2; | |||
7072 | if (!lineeditor_word_boundary (d, dir, d->current.edit_point, &i)) | |||
7073 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
7074 | return lineeditor_delete_chars (d, i, 1); | |||
7075 | } | |||
7076 | ||||
7077 | case LINEEDITOR_EV_END30: | |||
7078 | return lineeditor_move_edit_point (d, edited->length); | |||
7079 | ||||
7080 | case LINEEDITOR_EV_END_DOC31: | |||
7081 | return lineeditor_move_history (d, d->hist_last); | |||
7082 | ||||
7083 | case LINEEDITOR_EV_F132: | |||
7084 | case LINEEDITOR_EV_META_F133: | |||
7085 | case LINEEDITOR_EV_F234: | |||
7086 | case LINEEDITOR_EV_META_F235: | |||
7087 | case LINEEDITOR_EV_F336: | |||
7088 | case LINEEDITOR_EV_META_F337: | |||
7089 | case LINEEDITOR_EV_F438: | |||
7090 | case LINEEDITOR_EV_META_F439: | |||
7091 | #ifdef LINEEDITOR_SUPPORT_F5_TO_F12 | |||
7092 | case LINEEDITOR_EV_F540: | |||
7093 | case LINEEDITOR_EV_META_F541: | |||
7094 | case LINEEDITOR_EV_F642: | |||
7095 | case LINEEDITOR_EV_META_F643: | |||
7096 | case LINEEDITOR_EV_F744: | |||
7097 | case LINEEDITOR_EV_META_F745: | |||
7098 | case LINEEDITOR_EV_F846: | |||
7099 | case LINEEDITOR_EV_META_F847: | |||
7100 | case LINEEDITOR_EV_F948: | |||
7101 | case LINEEDITOR_EV_META_F949: | |||
7102 | case LINEEDITOR_EV_F1050: | |||
7103 | case LINEEDITOR_EV_META_F1051: | |||
7104 | case LINEEDITOR_EV_F1152: | |||
7105 | case LINEEDITOR_EV_META_F1153: | |||
7106 | case LINEEDITOR_EV_F1254: | |||
7107 | case LINEEDITOR_EV_META_F1255: | |||
7108 | #endif | |||
7109 | { | |||
7110 | ___Cunsigned int command[7]; | |||
7111 | command[0] = ___UNICODE_SHARP35; | |||
7112 | command[1] = ___UNICODE_VBAR124; | |||
7113 | command[2] = ___UNICODE_VBAR124; | |||
7114 | command[3] = ___UNICODE_SHARP35; | |||
7115 | command[4] = ___UNICODE_COMMA44; | |||
7116 | switch (ev->event_kind) | |||
7117 | { | |||
7118 | #ifdef LINEEDITOR_SUPPORT_F5_TO_F12 | |||
7119 | case LINEEDITOR_EV_F846: | |||
7120 | command[5] = ___UNICODE_LOWER_C99; | |||
7121 | break; | |||
7122 | case LINEEDITOR_EV_F948: | |||
7123 | command[5] = ___UNICODE_MINUS45; | |||
7124 | break; | |||
7125 | case LINEEDITOR_EV_F1050: | |||
7126 | command[5] = ___UNICODE_PLUS43; | |||
7127 | break; | |||
7128 | case LINEEDITOR_EV_F1152: | |||
7129 | command[5] = ___UNICODE_LOWER_S115; | |||
7130 | break; | |||
7131 | case LINEEDITOR_EV_F1254: | |||
7132 | command[5] = ___UNICODE_LOWER_L108; | |||
7133 | break; | |||
7134 | #endif | |||
7135 | default: | |||
7136 | command[5] = ___UNICODE_LOWER_T116; | |||
7137 | break; | |||
7138 | } | |||
7139 | command[6] = ___UNICODE_SEMICOLON59; | |||
7140 | if (lineeditor_move_edit_point (d, 0) | |||
7141 | == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
7142 | lineeditor_delete_chars (d, edited->length, 0) | |||
7143 | == ___FIX(___NO_ERR)(((long)(0))<<2) && | |||
7144 | lineeditor_insert_chars (d, command, 7) | |||
7145 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7146 | return lineeditor_line_done (d, 0); | |||
7147 | break; | |||
7148 | } | |||
7149 | } | |||
7150 | ||||
7151 | return ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2); | |||
7152 | } | |||
7153 | ||||
7154 | ||||
7155 | ___HIDDENstatic ___SCMOBJlong lineeditor_process_events | |||
7156 | ___P((___device_tty *self),(___device_tty *self) | |||
7157 | (self)(___device_tty *self) | |||
7158 | ___device_tty *self;)(___device_tty *self) | |||
7159 | { | |||
7160 | #define AGGREGATION_BUFFER_SIZE(80*50) (80*50) | |||
7161 | ||||
7162 | ___device_tty *d = self; | |||
7163 | ___SCMOBJlong e1; | |||
7164 | ___SCMOBJlong e2; | |||
7165 | ___Cunsigned int aggregation_buffer[AGGREGATION_BUFFER_SIZE(80*50)]; | |||
7166 | lineeditor_event ev; | |||
7167 | int i; | |||
7168 | struct lineeditor_state_undo_struct previous; | |||
7169 | ||||
7170 | /* | |||
7171 | * Process events only if no input line is currently available. | |||
7172 | */ | |||
7173 | ||||
7174 | if (d->input_line.buffer != NULL((void*)0)) | |||
7175 | return ___FIX(0)(((long)(0))<<2); | |||
7176 | ||||
7177 | /* | |||
7178 | * Process events only if no line editing output is pending. | |||
7179 | */ | |||
7180 | ||||
7181 | if ((e1 = lineeditor_output_drain (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7182 | return e1; | |||
7183 | ||||
7184 | /* | |||
7185 | * Save state so that we can undo if there is an error. | |||
7186 | */ | |||
7187 | ||||
7188 | d->current.paren_balance_trigger = 0; | |||
7189 | ||||
7190 | previous = d->current; | |||
7191 | ||||
7192 | i = 0; | |||
7193 | ||||
7194 | ev.event_kind = LINEEDITOR_EV_NONE0; | |||
7195 | ||||
7196 | for (;;) | |||
7197 | { | |||
7198 | if ((e1 = lineeditor_get_event (d, &ev)) != ___FIX(___NO_ERR)(((long)(0))<<2) || | |||
7199 | ev.event_kind == LINEEDITOR_EV_NONE0) | |||
7200 | break; | |||
7201 | ||||
7202 | if (ev.event_kind != LINEEDITOR_EV_KEY1 || | |||
7203 | ev.event_char < ___UNICODE_SPACE32 || | |||
7204 | ev.event_char == ___UNICODE_RUBOUT127) | |||
7205 | break; | |||
7206 | ||||
7207 | aggregation_buffer[i++] = ev.event_char; | |||
7208 | ||||
7209 | ev.event_kind = LINEEDITOR_EV_NONE0; | |||
7210 | ||||
7211 | if (i == AGGREGATION_BUFFER_SIZE(80*50)) | |||
7212 | break; | |||
7213 | } | |||
7214 | ||||
7215 | e2 = lineeditor_insert_chars (d, aggregation_buffer, i); | |||
7216 | if (e1 == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7217 | e1 = e2; | |||
7218 | ||||
7219 | e2 = lineeditor_process_single_event (d, &ev); | |||
7220 | if (e1 == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7221 | { | |||
7222 | if (ev.event_kind == LINEEDITOR_EV_NONE0) | |||
7223 | e1 = ___FIX(i)(((long)(i))<<2); | |||
7224 | else | |||
7225 | e1 = ___FIX(i+1)(((long)(i+1))<<2); | |||
7226 | } | |||
7227 | ||||
7228 | if (e1 == ___FIX(___INVALID_OP_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+7)))<<2)) | |||
7229 | { | |||
7230 | /* | |||
7231 | * Undo line editing operation. | |||
7232 | */ | |||
7233 | ||||
7234 | ___Cunsigned int c = ___UNICODE_BELL7; | |||
7235 | ||||
7236 | extensible_string_set_length | |||
7237 | (&d->output_char, | |||
7238 | 0, | |||
7239 | 1); /* ignore error */ | |||
7240 | ||||
7241 | d->output_char.length = 0; /* in case set_length failed */ | |||
7242 | d->output_char_lo = 0; | |||
7243 | ||||
7244 | d->current = previous; | |||
7245 | ||||
7246 | e1 = lineeditor_output (d, &c, 1); | |||
7247 | } | |||
7248 | ||||
7249 | if (d->current.paren_balance_trigger) | |||
7250 | { | |||
7251 | /* | |||
7252 | * Parenthesis balancing started in this round of event | |||
7253 | * processing. | |||
7254 | */ | |||
7255 | ||||
7256 | ___time duration; | |||
7257 | ||||
7258 | ___time_get_current_time (&d->current.paren_balance_end); | |||
7259 | ___time_from_nsecs (&duration, 0, d->paren_balance_duration_nsecs); | |||
7260 | ___time_add (&d->current.paren_balance_end, duration); | |||
7261 | ||||
7262 | d->current.paren_balance_in_progress = 1; | |||
7263 | } | |||
7264 | else if (d->current.paren_balance_in_progress) | |||
7265 | { | |||
7266 | /* | |||
7267 | * Parenthesis balancing did not start in this round of event | |||
7268 | * processing and parenthesis balancing is in progress, check if | |||
7269 | * parenthesis balancing should end. | |||
7270 | */ | |||
7271 | ||||
7272 | if (i > 0 || ev.event_kind != LINEEDITOR_EV_NONE0) | |||
7273 | lineeditor_end_paren_balance (d); /* ignore error */ | |||
7274 | else | |||
7275 | { | |||
7276 | ___time now; | |||
7277 | ___time_get_current_time (&now); | |||
7278 | if (!___time_less (now, d->current.paren_balance_end)) | |||
7279 | lineeditor_end_paren_balance (d); /* ignore error */ | |||
7280 | } | |||
7281 | } | |||
7282 | ||||
7283 | e2 = lineeditor_output_drain (d); | |||
7284 | if (e2 != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7285 | e1 = e2; | |||
7286 | ||||
7287 | return e1; | |||
7288 | } | |||
7289 | ||||
7290 | ||||
7291 | ___HIDDENstatic ___SCMOBJlong lineeditor_read_line | |||
7292 | ___P((___device_tty *self),(___device_tty *self) | |||
7293 | (self)(___device_tty *self) | |||
7294 | ___device_tty *self;)(___device_tty *self) | |||
7295 | { | |||
7296 | ___device_tty *d = self; | |||
7297 | ||||
7298 | if (!d->editing_line) | |||
7299 | { | |||
7300 | d->editing_line = 1; | |||
7301 | d->current.edit_point = 0; | |||
7302 | d->current.completion_point = 0; | |||
7303 | d->current.mark_point = 0; | |||
7304 | d->current.hist = d->hist_last; | |||
7305 | d->current.line_start = d->terminal_row * d->terminal_nb_cols + d->terminal_col; | |||
7306 | if (lineeditor_process_events (d) <= ___FIX(0)(((long)(0))<<2)) | |||
7307 | d->editing_line = 0; | |||
7308 | } | |||
7309 | else | |||
7310 | lineeditor_process_events (d); /* ignore error */ | |||
7311 | ||||
7312 | if (d->input_line.buffer == NULL((void*)0)) | |||
7313 | return ___ERR_CODE_EAGAIN(((long)(((11)==0?0:((((int)(-1))<<29)+(((int)(320))<< 16)+(11)))))<<2); | |||
7314 | ||||
7315 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7316 | } | |||
7317 | ||||
7318 | ||||
7319 | #endif | |||
7320 | ||||
7321 | ||||
7322 | /*****************************************************************************/ | |||
7323 | ||||
7324 | ||||
7325 | ___HIDDENstatic int ___device_tty_kind | |||
7326 | ___P((___device *self),(___device *self) | |||
7327 | (self)(___device *self) | |||
7328 | ___device *self;)(___device *self) | |||
7329 | { | |||
7330 | return ___TTY_DEVICE_KIND(15 +64); | |||
7331 | } | |||
7332 | ||||
7333 | ||||
7334 | ___HIDDENstatic ___SCMOBJlong ___device_tty_cleanup | |||
7335 | ___P((___device_tty *self),(___device_tty *self) | |||
7336 | ())(___device_tty *self); | |||
7337 | ||||
7338 | ||||
7339 | ___HIDDENstatic ___SCMOBJlong ___device_tty_close_raw_virt | |||
7340 | ___P((___device_stream *self,(___device_stream *self, int direction) | |||
7341 | int direction),(___device_stream *self, int direction) | |||
7342 | (self,(___device_stream *self, int direction) | |||
7343 | direction)(___device_stream *self, int direction) | |||
7344 | ___device_stream *self;(___device_stream *self, int direction) | |||
7345 | int direction;)(___device_stream *self, int direction) | |||
7346 | { | |||
7347 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7348 | int is_not_closed = 0; | |||
7349 | ||||
7350 | if (d->base.base.read_stage != ___STAGE_CLOSED3) | |||
7351 | is_not_closed |= ___DIRECTION_RD1; | |||
7352 | ||||
7353 | if (d->base.base.write_stage != ___STAGE_CLOSED3) | |||
7354 | is_not_closed |= ___DIRECTION_WR2; | |||
7355 | ||||
7356 | if (is_not_closed == 0) | |||
7357 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7358 | ||||
7359 | if ((is_not_closed & ~direction) == 0) | |||
7360 | { | |||
7361 | /* Close tty when both sides are closed. */ | |||
7362 | ||||
7363 | ___SCMOBJlong e; | |||
7364 | ||||
7365 | d->base.base.read_stage = ___STAGE_CLOSED3; /* avoid multiple closes */ | |||
7366 | d->base.base.write_stage = ___STAGE_CLOSED3; | |||
7367 | ||||
7368 | if ((e = ___device_tty_cleanup (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7369 | return e; | |||
7370 | } | |||
7371 | else if (direction & ___DIRECTION_RD1) | |||
7372 | d->base.base.read_stage = ___STAGE_CLOSED3; | |||
7373 | else if (direction & ___DIRECTION_WR2) | |||
7374 | d->base.base.write_stage = ___STAGE_CLOSED3; | |||
7375 | ||||
7376 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7377 | } | |||
7378 | ||||
7379 | ||||
7380 | ___HIDDENstatic ___SCMOBJlong ___device_tty_select_raw_virt | |||
7381 | ___P((___device_stream *self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7382 | ___BOOL for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7383 | int i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7384 | int pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7385 | ___device_select_state *state),(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7386 | (self,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7387 | for_writing,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7388 | i,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7389 | pass,(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7390 | state)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7391 | ___device_stream *self;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7392 | ___BOOL for_writing;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7393 | int i;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7394 | int pass;(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7395 | ___device_select_state *state;)(___device_stream *self, int for_writing, int i, int pass, ___device_select_state *state) | |||
7396 | { | |||
7397 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7398 | ___SCMOBJlong e; | |||
7399 | ||||
7400 | if ((e = ___device_tty_force_open (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7401 | return e; | |||
7402 | ||||
7403 | if ((for_writing ? d->base.base.write_stage : d->base.base.read_stage) | |||
7404 | != ___STAGE_OPEN0) | |||
7405 | return ___FIX(___CLOSED_DEVICE_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+6)))<<2); | |||
7406 | ||||
7407 | if (pass == ___SELECT_PASS_11) | |||
7408 | { | |||
7409 | #ifdef USE_POSIX | |||
7410 | ||||
7411 | ___device_select_add_fd (state, d->fd, for_writing); | |||
7412 | ||||
7413 | #endif | |||
7414 | ||||
7415 | #ifdef USE_WIN32 | |||
7416 | ||||
7417 | HANDLE wait_obj; | |||
7418 | ||||
7419 | if (for_writing) | |||
7420 | wait_obj = d->hin; | |||
7421 | else | |||
7422 | wait_obj = d->hout; | |||
7423 | ||||
7424 | ___device_select_add_wait_obj (state, i, wait_obj); | |||
7425 | ||||
7426 | #endif | |||
7427 | ||||
7428 | #ifdef USE_LINEEDITOR | |||
7429 | ||||
7430 | if (!for_writing) | |||
7431 | { | |||
7432 | if (lineeditor_read_ready (d)) | |||
7433 | ___device_select_add_timeout | |||
7434 | (state, | |||
7435 | i, | |||
7436 | ___time_mod.time_neg_infinity); | |||
7437 | else if (d->current.paren_balance_in_progress) | |||
7438 | ___device_select_add_timeout | |||
7439 | (state, | |||
7440 | i, | |||
7441 | d->current.paren_balance_end); | |||
7442 | } | |||
7443 | ||||
7444 | #endif | |||
7445 | ||||
7446 | return ___FIX(___SELECT_SETUP_DONE)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+14)))<<2); | |||
7447 | } | |||
7448 | ||||
7449 | /* pass == ___SELECT_PASS_CHECK */ | |||
7450 | ||||
7451 | if (for_writing) | |||
7452 | { | |||
7453 | #ifdef USE_POSIX | |||
7454 | ||||
7455 | if (___FD_ISSET(d->fd, &state->writefds)((((&state->writefds)->__fds_bits)[((d->fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ( (d->fd) % (8 * (int) sizeof (__fd_mask))))) != 0)) | |||
7456 | state->devs[i] = NULL((void*)0); | |||
7457 | ||||
7458 | #endif | |||
7459 | ||||
7460 | #ifdef USE_WIN32 | |||
7461 | ||||
7462 | if (state->devs_next[i] != -1) | |||
7463 | state->devs[i] = NULL((void*)0); | |||
7464 | ||||
7465 | #endif | |||
7466 | } | |||
7467 | else | |||
7468 | { | |||
7469 | #ifdef USE_POSIX | |||
7470 | ||||
7471 | if (___FD_ISSET(d->fd, &state->readfds)((((&state->readfds)->__fds_bits)[((d->fd) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << (( d->fd) % (8 * (int) sizeof (__fd_mask))))) != 0)) | |||
7472 | state->devs[i] = NULL((void*)0); | |||
7473 | ||||
7474 | #endif | |||
7475 | ||||
7476 | #ifdef USE_WIN32 | |||
7477 | ||||
7478 | if (state->devs_next[i] != -1) | |||
7479 | state->devs[i] = NULL((void*)0); | |||
7480 | ||||
7481 | #endif | |||
7482 | ||||
7483 | #ifdef USE_LINEEDITOR | |||
7484 | ||||
7485 | if (lineeditor_read_ready (d) || | |||
7486 | (d->current.paren_balance_in_progress && | |||
7487 | state->timeout_reached && | |||
7488 | !___time_less (state->timeout, d->current.paren_balance_end))) | |||
7489 | state->devs[i] = NULL((void*)0); | |||
7490 | ||||
7491 | #endif | |||
7492 | } | |||
7493 | ||||
7494 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7495 | } | |||
7496 | ||||
7497 | ||||
7498 | ___HIDDENstatic ___SCMOBJlong ___device_tty_release_raw_virt | |||
7499 | ___P((___device_stream *self),(___device_stream *self) | |||
7500 | (self)(___device_stream *self) | |||
7501 | ___device_stream *self;)(___device_stream *self) | |||
7502 | { | |||
7503 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7504 | } | |||
7505 | ||||
7506 | ||||
7507 | ___HIDDENstatic ___SCMOBJlong ___device_tty_force_output_raw_virt | |||
7508 | ___P((___device_stream *self,(___device_stream *self, int level) | |||
7509 | int level),(___device_stream *self, int level) | |||
7510 | (self,(___device_stream *self, int level) | |||
7511 | level)(___device_stream *self, int level) | |||
7512 | ___device_stream *self;(___device_stream *self, int level) | |||
7513 | int level;)(___device_stream *self, int level) | |||
7514 | { | |||
7515 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7516 | ||||
7517 | #ifdef USE_LINEEDITOR | |||
7518 | ||||
7519 | if (d->stage >= TTY_STAGE_INIT_DONE3) | |||
7520 | return lineeditor_output_drain (d); | |||
7521 | ||||
7522 | #endif | |||
7523 | ||||
7524 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7525 | } | |||
7526 | ||||
7527 | ||||
7528 | ___HIDDENstatic ___SCMOBJlong ___device_tty_seek_raw_virt | |||
7529 | ___P((___device_stream *self,(___device_stream *self, ___stream_index *pos, int whence) | |||
7530 | ___stream_index *pos,(___device_stream *self, ___stream_index *pos, int whence) | |||
7531 | int whence),(___device_stream *self, ___stream_index *pos, int whence) | |||
7532 | (self,(___device_stream *self, ___stream_index *pos, int whence) | |||
7533 | pos,(___device_stream *self, ___stream_index *pos, int whence) | |||
7534 | whence)(___device_stream *self, ___stream_index *pos, int whence) | |||
7535 | ___device_stream *self;(___device_stream *self, ___stream_index *pos, int whence) | |||
7536 | ___stream_index *pos;(___device_stream *self, ___stream_index *pos, int whence) | |||
7537 | int whence;)(___device_stream *self, ___stream_index *pos, int whence) | |||
7538 | { | |||
7539 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7540 | ||||
7541 | return ___FIX(___UNKNOWN_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+3)))<<2); | |||
7542 | } | |||
7543 | ||||
7544 | ||||
7545 | ___HIDDENstatic ___SCMOBJlong ___device_tty_read_raw_virt | |||
7546 | ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7547 | ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7548 | ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7549 | ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7550 | (self,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7551 | buf,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7552 | len,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7553 | len_done)(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7554 | ___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7555 | ___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7556 | ___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7557 | ___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7558 | { | |||
7559 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7560 | ___SCMOBJlong e; | |||
7561 | ||||
7562 | if ((e = ___device_tty_force_open (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7563 | return e; | |||
7564 | ||||
7565 | len = TTY_CHAR_SELECT(1,2)1; | |||
7566 | ||||
7567 | #ifdef USE_LINEEDITOR | |||
7568 | ||||
7569 | { | |||
7570 | int lo = d->lineeditor_input_byte_lo; | |||
7571 | int hi = d->lineeditor_input_byte_hi; | |||
7572 | int n = hi - lo; | |||
7573 | int limit; | |||
7574 | ||||
7575 | if (n > len) | |||
7576 | n = len; | |||
7577 | ||||
7578 | if (n <= 0) | |||
7579 | { | |||
7580 | int char_avail; | |||
7581 | ___Cunsigned int *char_buf_end; | |||
7582 | int byte_avail; | |||
7583 | ___U8unsigned char *byte_buf_end; | |||
7584 | ||||
7585 | char_avail = d->input_line.length - d->input_line_lo; | |||
7586 | ||||
7587 | if (char_avail <= 0) | |||
7588 | { | |||
7589 | if (d->lineeditor_mode == LINEEDITOR_MODE_DISABLE0 || d->input_raw) | |||
7590 | goto read_raw; | |||
7591 | ||||
7592 | if ((e = lineeditor_read_line (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7593 | return e; | |||
7594 | ||||
7595 | char_avail = d->input_line.length - d->input_line_lo; | |||
7596 | ||||
7597 | /* | |||
7598 | * It is possible that char_avail == 0. This happens when | |||
7599 | * the end-of-file character is typed (e.g. ctrl-d). | |||
7600 | */ | |||
7601 | } | |||
7602 | ||||
7603 | char_buf_end = d->input_line.buffer + d->input_line.length; | |||
7604 | ||||
7605 | byte_avail = ___NBELEMS(d->lineeditor_input_byte)(sizeof (d->lineeditor_input_byte) / sizeof ((d->lineeditor_input_byte )[0])); | |||
7606 | byte_buf_end = d->lineeditor_input_byte + byte_avail; | |||
7607 | ||||
7608 | while (chars_to_bytes (char_buf_end - char_avail, | |||
7609 | &char_avail, | |||
7610 | byte_buf_end - byte_avail, | |||
7611 | &byte_avail, | |||
7612 | &d->input_encoding_state) | |||
7613 | == ___ILLEGAL_CHAR2) | |||
7614 | char_avail--; /* skip over the illegal characters */ | |||
7615 | ||||
7616 | d->input_line_lo = d->input_line.length - char_avail; | |||
7617 | ||||
7618 | if (char_avail <= 0) | |||
7619 | { | |||
7620 | extensible_string_cleanup (&d->input_line); | |||
7621 | d->input_line.buffer = NULL((void*)0); | |||
7622 | } | |||
7623 | ||||
7624 | n = ___NBELEMS(d->lineeditor_input_byte)(sizeof (d->lineeditor_input_byte) / sizeof ((d->lineeditor_input_byte )[0])) - byte_avail; | |||
7625 | lo = 0; | |||
7626 | hi = n; | |||
7627 | d->lineeditor_input_byte_hi = hi; | |||
7628 | } | |||
7629 | ||||
7630 | limit = lo + n; | |||
7631 | ||||
7632 | while (lo < limit) | |||
7633 | *buf++ = d->lineeditor_input_byte[lo++]; | |||
7634 | ||||
7635 | if (lo < hi) | |||
7636 | d->lineeditor_input_byte_lo = lo; | |||
7637 | else | |||
7638 | { | |||
7639 | d->lineeditor_input_byte_lo = 0; | |||
7640 | d->lineeditor_input_byte_hi = 0; | |||
7641 | } | |||
7642 | ||||
7643 | *len_done = n; | |||
7644 | ||||
7645 | #ifdef ___DEBUG_TTY | |||
7646 | ||||
7647 | { | |||
7648 | int i; | |||
7649 | ||||
7650 | ___printf ("___device_tty_read_raw_virt nb_bytes: %d ", *len_done); | |||
7651 | ||||
7652 | for (i=0; i<*len_done; i++) | |||
7653 | ___printf (" %02x", buf[i]); | |||
7654 | ||||
7655 | ___printf ("\n"); | |||
7656 | } | |||
7657 | ||||
7658 | #endif | |||
7659 | ||||
7660 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7661 | } | |||
7662 | ||||
7663 | read_raw:; | |||
7664 | ||||
7665 | #endif | |||
7666 | ||||
7667 | return ___device_tty_read_raw_no_lineeditor | |||
7668 | (d, | |||
7669 | buf, | |||
7670 | len, | |||
7671 | len_done); | |||
7672 | } | |||
7673 | ||||
7674 | ||||
7675 | ___HIDDENstatic ___SCMOBJlong ___device_tty_write_raw_virt | |||
7676 | ___P((___device_stream *self,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7677 | ___U8 *buf,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7678 | ___stream_index len,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7679 | ___stream_index *len_done),(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7680 | (self,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7681 | buf,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7682 | len,(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7683 | len_done)(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7684 | ___device_stream *self;(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7685 | ___U8 *buf;(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7686 | ___stream_index len;(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7687 | ___stream_index *len_done;)(___device_stream *self, unsigned char *buf, ___stream_index len , ___stream_index *len_done) | |||
7688 | { | |||
7689 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7690 | ___SCMOBJlong e; | |||
7691 | ||||
7692 | if ((e = ___device_tty_force_open (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
| ||||
7693 | return e; | |||
7694 | ||||
7695 | #ifdef USE_LINEEDITOR | |||
7696 | ||||
7697 | if (d->lineeditor_mode != LINEEDITOR_MODE_DISABLE0) | |||
7698 | { | |||
7699 | if (!d->output_raw) | |||
7700 | { | |||
7701 | ___SCMOBJlong e; | |||
7702 | ___U8unsigned char *byte_buf_end; | |||
7703 | int byte_buf_avail; | |||
7704 | ||||
7705 | if ((e = lineeditor_end_paren_balance (d)) | |||
7706 | != ___FIX(___NO_ERR)(((long)(0))<<2) || | |||
7707 | (e = lineeditor_output_set_attrs (d, d->output_attrs)) | |||
7708 | != ___FIX(___NO_ERR)(((long)(0))<<2) || | |||
7709 | (e = lineeditor_output_drain (d)) | |||
7710 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7711 | return e; | |||
7712 | ||||
7713 | byte_buf_end = buf + len; | |||
7714 | byte_buf_avail = len + d->output_char_incomplete; | |||
7715 | ||||
7716 | /* convert the bytes to characters */ | |||
7717 | ||||
7718 | while (byte_buf_avail > 0) | |||
7719 | { | |||
7720 | ___Cunsigned int char_buf[128]; | |||
7721 | int char_buf_avail = ___NBELEMS(char_buf)(sizeof (char_buf) / sizeof ((char_buf)[0])); | |||
7722 | int orig_byte_buf_avail = byte_buf_avail; | |||
7723 | int code; | |||
7724 | ||||
7725 | code = chars_from_bytes (char_buf, | |||
7726 | &char_buf_avail, | |||
7727 | byte_buf_end - byte_buf_avail, | |||
7728 | &byte_buf_avail, | |||
7729 | &d->output_decoding_state); | |||
7730 | ||||
7731 | switch (code) | |||
7732 | { | |||
7733 | case ___CONVERSION_DONE0: | |||
7734 | if ((e = lineeditor_output | |||
7735 | (d, | |||
7736 | char_buf, | |||
7737 | ___NBELEMS(char_buf)(sizeof (char_buf) / sizeof ((char_buf)[0])) - char_buf_avail)) | |||
7738 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7739 | { | |||
7740 | /*******************************/ | |||
7741 | return e; | |||
7742 | } | |||
7743 | lineeditor_output_drain (d); /* ignore error */ | |||
7744 | break; | |||
7745 | ||||
7746 | case ___INCOMPLETE_CHAR1: | |||
7747 | *len_done = byte_buf_avail - d->output_char_incomplete; | |||
7748 | d->output_char_incomplete = byte_buf_avail; | |||
7749 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7750 | ||||
7751 | case ___ILLEGAL_CHAR2: | |||
7752 | /* ignore illegal characters */ | |||
7753 | break; | |||
7754 | } | |||
7755 | } | |||
7756 | ||||
7757 | *len_done = len; | |||
7758 | d->output_char_incomplete = 0; | |||
7759 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7760 | } | |||
7761 | } | |||
7762 | ||||
7763 | #endif | |||
7764 | ||||
7765 | return ___device_tty_write_raw_no_lineeditor (d, buf, len, len_done); | |||
7766 | } | |||
7767 | ||||
7768 | ||||
7769 | ___HIDDENstatic ___SCMOBJlong ___device_tty_width_virt | |||
7770 | ___P((___device_stream *self),(___device_stream *self) | |||
7771 | (self)(___device_stream *self) | |||
7772 | ___device_stream *self;)(___device_stream *self) | |||
7773 | { | |||
7774 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7775 | ___SCMOBJlong e; | |||
7776 | ||||
7777 | if ((e = ___device_tty_force_open (d)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7778 | return e; | |||
7779 | ||||
7780 | if ((e = ___device_tty_update_size (d)) == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7781 | return ___FIX(d->terminal_nb_cols)(((long)(d->terminal_nb_cols))<<2); | |||
7782 | ||||
7783 | return e; | |||
7784 | } | |||
7785 | ||||
7786 | ||||
7787 | ___HIDDENstatic ___SCMOBJlong ___device_tty_default_options_virt | |||
7788 | ___P((___device_stream *self),(___device_stream *self) | |||
7789 | (self)(___device_stream *self) | |||
7790 | ___device_stream *self;)(___device_stream *self) | |||
7791 | { | |||
7792 | int settings = ___setup_params.terminal_settings; | |||
7793 | int char_encoding_errors = ___CHAR_ENCODING_ERRORS(settings)((settings)&(3<<5)); | |||
7794 | int char_encoding = ___CHAR_ENCODING(settings)((settings)&(31<<0)); | |||
7795 | int eol_encoding = ___EOL_ENCODING(settings)((settings)&(3<<7)); | |||
7796 | int buffering = ___BUFFERING(settings)((settings)&(3<<9)); | |||
7797 | ||||
7798 | if (char_encoding_errors == 0) | |||
7799 | char_encoding_errors = ___CHAR_ENCODING_ERRORS_ON(1<<5); | |||
7800 | ||||
7801 | switch (char_encoding) | |||
7802 | { | |||
7803 | case ___CHAR_ENCODING_UCS_2(13<<0): | |||
7804 | #ifdef ___BIG_ENDIAN | |||
7805 | char_encoding = ___CHAR_ENCODING_UCS_2BE(14<<0); | |||
7806 | #else | |||
7807 | char_encoding = ___CHAR_ENCODING_UCS_2LE(15<<0); | |||
7808 | #endif | |||
7809 | break; | |||
7810 | ||||
7811 | case ___CHAR_ENCODING_UCS_4(16<<0): | |||
7812 | #ifdef ___BIG_ENDIAN | |||
7813 | char_encoding = ___CHAR_ENCODING_UCS_4BE(17<<0); | |||
7814 | #else | |||
7815 | char_encoding = ___CHAR_ENCODING_UCS_4LE(18<<0); | |||
7816 | #endif | |||
7817 | break; | |||
7818 | ||||
7819 | case 0: | |||
7820 | #ifdef USE_WIN32 | |||
7821 | char_encoding = | |||
7822 | TTY_CHAR_SELECT(___CHAR_ENCODING_ISO_8859_1,___CHAR_ENCODING_UCS_2LE)(2<<0); | |||
7823 | #else | |||
7824 | char_encoding = ___CHAR_ENCODING_ISO_8859_1(2<<0); | |||
7825 | #endif | |||
7826 | break; | |||
7827 | } | |||
7828 | ||||
7829 | if (eol_encoding == 0) | |||
7830 | { | |||
7831 | #ifdef USE_WIN32 | |||
7832 | eol_encoding = ___EOL_ENCODING_CRLF(3<<7); | |||
7833 | #else | |||
7834 | eol_encoding = ___EOL_ENCODING_LF(1<<7); | |||
7835 | #endif | |||
7836 | } | |||
7837 | ||||
7838 | if (buffering == 0) | |||
7839 | buffering = ___NO_BUFFERING(1<<9); | |||
7840 | ||||
7841 | #ifdef ___DEBUG_TTY | |||
7842 | ||||
7843 | ___printf ("terminal char_encoding=%d eol_encoding=%d buffering=%d\n", | |||
7844 | char_encoding, | |||
7845 | eol_encoding, | |||
7846 | buffering); | |||
7847 | ||||
7848 | #endif | |||
7849 | ||||
7850 | return ___FIX(___STREAM_OPTIONS(char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2) | |||
7851 | char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2) | |||
7852 | eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2) | |||
7853 | buffering,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2) | |||
7854 | char_encoding_errors,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2) | |||
7855 | char_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2) | |||
7856 | eol_encoding,(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2) | |||
7857 | buffering))(((long)((char_encoding_errors+char_encoding+eol_encoding+buffering )+((char_encoding_errors+char_encoding+eol_encoding+buffering )<<15)))<<2); | |||
7858 | } | |||
7859 | ||||
7860 | ||||
7861 | ___HIDDENstatic ___SCMOBJlong ___device_tty_options_set_virt | |||
7862 | ___P((___device_stream *self,(___device_stream *self, long options) | |||
7863 | ___SCMOBJ options),(___device_stream *self, long options) | |||
7864 | (self,(___device_stream *self, long options) | |||
7865 | options)(___device_stream *self, long options) | |||
7866 | ___device_stream *self;(___device_stream *self, long options) | |||
7867 | ___SCMOBJ options;)(___device_stream *self, long options) | |||
7868 | { | |||
7869 | ___device_tty *d = ___CAST(___device_tty*,self)((___device_tty*)(self)); | |||
7870 | int opts = ___INT(options)((options)>>2); | |||
7871 | int input_opts = ___STREAM_OPTIONS_INPUT(opts)((opts)&((1<<15)-1)); | |||
7872 | int output_opts = ___STREAM_OPTIONS_OUTPUT(opts)(((opts)>>15)&((1<<15)-1)); | |||
7873 | ||||
7874 | d->input_decoding_state = input_opts; | |||
7875 | d->input_encoding_state = input_opts; | |||
7876 | d->output_decoding_state = output_opts; | |||
7877 | d->output_encoding_state = output_opts; | |||
7878 | ||||
7879 | #ifdef ___DEBUG_TTY | |||
7880 | ___printf ("input_opts=%d output_opts=%d\n", input_opts, output_opts); | |||
7881 | #endif | |||
7882 | ||||
7883 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7884 | } | |||
7885 | ||||
7886 | ||||
7887 | ___HIDDENstatic ___device_tty_vtbl ___device_tty_table = | |||
7888 | { | |||
7889 | { | |||
7890 | { | |||
7891 | ___device_tty_kind, | |||
7892 | ___device_stream_select_virt, | |||
7893 | ___device_stream_release_virt, | |||
7894 | ___device_stream_force_output_virt, | |||
7895 | ___device_stream_close_virt | |||
7896 | }, | |||
7897 | ___device_tty_select_raw_virt, | |||
7898 | ___device_tty_release_raw_virt, | |||
7899 | ___device_tty_force_output_raw_virt, | |||
7900 | ___device_tty_close_raw_virt, | |||
7901 | ___device_tty_seek_raw_virt, | |||
7902 | ___device_tty_read_raw_virt, | |||
7903 | ___device_tty_write_raw_virt, | |||
7904 | ___device_tty_width_virt, | |||
7905 | ___device_tty_default_options_virt, | |||
7906 | ___device_tty_options_set_virt | |||
7907 | } | |||
7908 | }; | |||
7909 | ||||
7910 | ||||
7911 | ___HIDDENstatic ___SCMOBJlong ___device_tty_setup | |||
7912 | ___P((___device_tty *self,(___device_tty *self, int plain) | |||
7913 | int plain),(___device_tty *self, int plain) | |||
7914 | (self,(___device_tty *self, int plain) | |||
7915 | plain)(___device_tty *self, int plain) | |||
7916 | ___device_tty *self;(___device_tty *self, int plain) | |||
7917 | int plain;)(___device_tty *self, int plain) | |||
7918 | { | |||
7919 | ___device_tty *d = self; | |||
7920 | ___SCMOBJlong e = ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7921 | ||||
7922 | #ifdef USE_LINEEDITOR | |||
7923 | ||||
7924 | e = lineeditor_setup (d, plain); | |||
7925 | ||||
7926 | #endif | |||
7927 | ||||
7928 | return e; | |||
7929 | } | |||
7930 | ||||
7931 | ||||
7932 | ___HIDDENstatic ___SCMOBJlong ___device_tty_cleanup | |||
7933 | ___P((___device_tty *self),(___device_tty *self) | |||
7934 | (self)(___device_tty *self) | |||
7935 | ___device_tty *self;)(___device_tty *self) | |||
7936 | { | |||
7937 | ___device_tty *d = self; | |||
7938 | ___SCMOBJlong e; | |||
7939 | ||||
7940 | #ifdef USE_LINEEDITOR | |||
7941 | ||||
7942 | lineeditor_cleanup (d); | |||
7943 | ||||
7944 | #endif | |||
7945 | ||||
7946 | if (d->stage >= TTY_STAGE_MODE_NOT_SAVED1) | |||
7947 | { | |||
7948 | if (d->stage >= TTY_STAGE_MODE_NOT_SET2) | |||
7949 | { | |||
7950 | if ((e = ___device_tty_mode_restore (d, 1)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
7951 | return e; | |||
7952 | } | |||
7953 | ||||
7954 | if ((d->base.base.close_direction & d->base.base.direction) | |||
7955 | == d->base.base.direction) | |||
7956 | { | |||
7957 | #ifdef USE_POSIX | |||
7958 | if (close_no_EINTR (d->fd) < 0) | |||
7959 | return err_code_from_errno ()___err_code_from_errno(); | |||
7960 | #endif | |||
7961 | ||||
7962 | #ifdef USE_WIN32 | |||
7963 | if (!CloseHandle (d->hin)) | |||
7964 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
7965 | if (!CloseHandle (d->hout)) | |||
7966 | return err_code_from_GetLastError ()___err_code_from_GetLastError(); | |||
7967 | #endif | |||
7968 | } | |||
7969 | } | |||
7970 | ||||
7971 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
7972 | } | |||
7973 | ||||
7974 | ||||
7975 | #ifndef USE_POSIX | |||
7976 | #ifndef USE_WIN32 | |||
7977 | ||||
7978 | ||||
7979 | ___SCMOBJlong ___device_tty_setup_from_stdio | |||
7980 | ___P((___device_tty **dev,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7981 | ___device_group *dgroup,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7982 | int direction),(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7983 | (dev,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7984 | dgroup,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7985 | direction)(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7986 | ___device_tty **dev;(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7987 | ___device_group *dgroup;(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7988 | int direction;)(___device_tty **dev, ___device_group *dgroup, int direction) | |||
7989 | { | |||
7990 | ___device_tty *d; | |||
7991 | ___SCMOBJlong e; | |||
7992 | ||||
7993 | d = ___CAST(___device_tty*,((___device_tty*)(___alloc_mem (sizeof (___device_tty)))) | |||
7994 | ___alloc_mem (sizeof (___device_tty)))((___device_tty*)(___alloc_mem (sizeof (___device_tty)))); | |||
7995 | ||||
7996 | if (d == NULL((void*)0)) | |||
7997 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
7998 | ||||
7999 | d->base.base.vtbl = &___device_tty_table; | |||
8000 | ||||
8001 | d->stage = TTY_STAGE_NOT_OPENED0; | |||
8002 | ||||
8003 | *dev = d; | |||
8004 | ||||
8005 | if ((e = ___device_tty_setup (d, 1)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8006 | { | |||
8007 | ___free_mem (d); | |||
8008 | return e; | |||
8009 | } | |||
8010 | ||||
8011 | return ___device_stream_setup | |||
8012 | (&d->base, | |||
8013 | dgroup, | |||
8014 | direction, | |||
8015 | 0); | |||
8016 | } | |||
8017 | ||||
8018 | ||||
8019 | #endif | |||
8020 | #endif | |||
8021 | ||||
8022 | ||||
8023 | #ifdef USE_POSIX | |||
8024 | ||||
8025 | ||||
8026 | ___SCMOBJlong ___device_tty_setup_from_fd | |||
8027 | ___P((___device_tty **dev,(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8028 | ___device_group *dgroup,(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8029 | int fd,(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8030 | int direction),(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8031 | (dev,(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8032 | dgroup,(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8033 | fd,(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8034 | direction)(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8035 | ___device_tty **dev;(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8036 | ___device_group *dgroup;(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8037 | int fd;(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8038 | int direction;(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8039 | int close_direction;)(___device_tty **dev, ___device_group *dgroup, int fd, int direction ) | |||
8040 | { | |||
8041 | ___device_tty *d; | |||
8042 | ___SCMOBJlong e; | |||
8043 | int plain = (fd == STDIN_FILENO0) || | |||
8044 | (fd == STDOUT_FILENO1) || | |||
8045 | (fd == STDERR_FILENO2); | |||
8046 | ||||
8047 | d = ___CAST(___device_tty*,((___device_tty*)(___alloc_mem (sizeof (___device_tty)))) | |||
8048 | ___alloc_mem (sizeof (___device_tty)))((___device_tty*)(___alloc_mem (sizeof (___device_tty)))); | |||
8049 | ||||
8050 | if (d == NULL((void*)0)) | |||
8051 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
8052 | ||||
8053 | d->base.base.vtbl = &___device_tty_table; | |||
8054 | ||||
8055 | d->stage = (fd < 0) ? TTY_STAGE_NOT_OPENED0 : TTY_STAGE_MODE_NOT_SAVED1; | |||
8056 | d->fd = fd; | |||
8057 | ||||
8058 | *dev = d; | |||
8059 | ||||
8060 | if ((e = ___device_tty_setup (d, plain)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8061 | { | |||
8062 | ___free_mem (d); | |||
8063 | return e; | |||
8064 | } | |||
8065 | ||||
8066 | return ___device_stream_setup | |||
8067 | (&d->base, | |||
8068 | dgroup, | |||
8069 | direction, | |||
8070 | 0); | |||
8071 | } | |||
8072 | ||||
8073 | ||||
8074 | #endif | |||
8075 | ||||
8076 | ||||
8077 | #ifdef USE_WIN32 | |||
8078 | ||||
8079 | ||||
8080 | ___SCMOBJlong ___device_tty_setup_from_console | |||
8081 | ___P((___device_tty **dev,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8082 | ___device_group *dgroup,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8083 | int direction),(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8084 | (dev,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8085 | dgroup,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8086 | direction)(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8087 | ___device_tty **dev;(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8088 | ___device_group *dgroup;(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8089 | int direction;)(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8090 | { | |||
8091 | ___device_tty *d; | |||
8092 | ___SCMOBJlong e; | |||
8093 | ||||
8094 | d = ___CAST(___device_tty*,((___device_tty*)(___alloc_mem (sizeof (___device_tty)))) | |||
8095 | ___alloc_mem (sizeof (___device_tty)))((___device_tty*)(___alloc_mem (sizeof (___device_tty)))); | |||
8096 | ||||
8097 | if (d == NULL((void*)0)) | |||
8098 | return ___FIX(___HEAP_OVERFLOW_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+5)))<<2); | |||
8099 | ||||
8100 | d->base.base.vtbl = &___device_tty_table; | |||
8101 | ||||
8102 | d->stage = TTY_STAGE_NOT_OPENED0; | |||
8103 | ||||
8104 | *dev = d; | |||
8105 | ||||
8106 | if ((e = ___device_tty_setup (d, 0)) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8107 | { | |||
8108 | ___free_mem (d); | |||
8109 | return e; | |||
8110 | } | |||
8111 | ||||
8112 | return ___device_stream_setup | |||
8113 | (&d->base, | |||
8114 | dgroup, | |||
8115 | direction, | |||
8116 | 0); | |||
8117 | } | |||
8118 | ||||
8119 | ||||
8120 | #endif | |||
8121 | ||||
8122 | ||||
8123 | ___SCMOBJlong ___device_tty_setup_console | |||
8124 | ___P((___device_tty **dev,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8125 | ___device_group *dgroup,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8126 | int direction),(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8127 | (dev,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8128 | dgroup,(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8129 | direction)(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8130 | ___device_tty **dev;(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8131 | ___device_group *dgroup;(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8132 | int direction;)(___device_tty **dev, ___device_group *dgroup, int direction) | |||
8133 | { | |||
8134 | #ifndef USE_POSIX | |||
8135 | #ifndef USE_WIN32 | |||
8136 | ||||
8137 | return ___device_tty_setup_from_stdio (dev, | |||
8138 | dgroup, | |||
8139 | direction); | |||
8140 | ||||
8141 | #endif | |||
8142 | #endif | |||
8143 | ||||
8144 | #ifdef USE_POSIX | |||
8145 | ||||
8146 | return ___device_tty_setup_from_fd (dev, | |||
8147 | dgroup, | |||
8148 | -1, | |||
8149 | direction); | |||
8150 | ||||
8151 | #endif | |||
8152 | ||||
8153 | #ifdef USE_WIN32 | |||
8154 | ||||
8155 | return ___device_tty_setup_from_console (dev, | |||
8156 | dgroup, | |||
8157 | direction); | |||
8158 | ||||
8159 | #endif | |||
8160 | } | |||
8161 | ||||
8162 | ||||
8163 | ___tty_module ___tty_mod = | |||
8164 | { | |||
8165 | 0, | |||
8166 | NULL((void*)0), | |||
8167 | NULL((void*)0), | |||
8168 | NULL((void*)0), | |||
8169 | NULL((void*)0), | |||
8170 | { | |||
8171 | #ifdef TERMINAL_EMULATION_USES_CURSES | |||
8172 | { | |||
8173 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | |||
8174 | 0, | |||
8175 | ___FIX(___NO_ERR)(((long)(0))<<2) | |||
8176 | }, | |||
8177 | #endif | |||
8178 | { | |||
8179 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | |||
8180 | 0, | |||
8181 | ___FIX(___NO_ERR)(((long)(0))<<2) | |||
8182 | } | |||
8183 | } | |||
8184 | ||||
8185 | #ifdef IO_MODULE_INIT | |||
8186 | ___TTY_MODULE_INIT | |||
8187 | #endif | |||
8188 | }; | |||
8189 | ||||
8190 | ||||
8191 | /*---------------------------------------------------------------------------*/ | |||
8192 | ||||
8193 | /* Tty device operations. */ | |||
8194 | ||||
8195 | ||||
8196 | ___SCMOBJlong ___os_device_tty_type_set | |||
8197 | ___P((___SCMOBJ dev,(long dev, long term_type, long emacs_bindings) | |||
8198 | ___SCMOBJ term_type,(long dev, long term_type, long emacs_bindings) | |||
8199 | ___SCMOBJ emacs_bindings),(long dev, long term_type, long emacs_bindings) | |||
8200 | (dev,(long dev, long term_type, long emacs_bindings) | |||
8201 | term_type,(long dev, long term_type, long emacs_bindings) | |||
8202 | emacs_bindings)(long dev, long term_type, long emacs_bindings) | |||
8203 | ___SCMOBJ dev;(long dev, long term_type, long emacs_bindings) | |||
8204 | ___SCMOBJ term_type;(long dev, long term_type, long emacs_bindings) | |||
8205 | ___SCMOBJ emacs_bindings;)(long dev, long term_type, long emacs_bindings) | |||
8206 | { | |||
8207 | return ___FIX(___UNIMPL_ERR)(((long)((((((int)(-1))<<29)+(((int)(448))<<16)+( 0))+4)))<<2); | |||
8208 | } | |||
8209 | ||||
8210 | ||||
8211 | ___SCMOBJlong ___os_device_tty_text_attributes_set | |||
8212 | ___P((___SCMOBJ dev,(long dev, long input, long output) | |||
8213 | ___SCMOBJ input,(long dev, long input, long output) | |||
8214 | ___SCMOBJ output),(long dev, long input, long output) | |||
8215 | (dev,(long dev, long input, long output) | |||
8216 | input,(long dev, long input, long output) | |||
8217 | output)(long dev, long input, long output) | |||
8218 | ___SCMOBJ dev;(long dev, long input, long output) | |||
8219 | ___SCMOBJ input;(long dev, long input, long output) | |||
8220 | ___SCMOBJ output;)(long dev, long input, long output) | |||
8221 | { | |||
8222 | ___device_tty *d = | |||
8223 | ___CAST(___device_tty*,___FIELD(dev,___FOREIGN_PTR))((___device_tty*)((*((((long*)((dev)-(1)))+1)+2)))); | |||
8224 | ||||
8225 | d->input_attrs = ___INT(input)((input)>>2); | |||
8226 | d->output_attrs = ___INT(output)((output)>>2); | |||
8227 | ||||
8228 | return ___VOID((((long)(-5))<<2)+2); | |||
8229 | } | |||
8230 | ||||
8231 | ||||
8232 | ___SCMOBJlong ___os_device_tty_history | |||
8233 | ___P((___SCMOBJ dev),(long dev) | |||
8234 | (dev)(long dev) | |||
8235 | ___SCMOBJ dev;)(long dev) | |||
8236 | { | |||
8237 | ___device_tty *d = | |||
8238 | ___CAST(___device_tty*,___FIELD(dev,___FOREIGN_PTR))((___device_tty*)((*((((long*)((dev)-(1)))+1)+2)))); | |||
8239 | ___SCMOBJlong e; | |||
8240 | ___SCMOBJlong result; | |||
8241 | extensible_string hist; | |||
8242 | ||||
8243 | if ((e = extensible_string_setup (&hist, 0)) | |||
8244 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8245 | result = e; | |||
8246 | else | |||
8247 | { | |||
8248 | ___Cunsigned int nul = ___UNICODE_NUL0; | |||
8249 | ___Cunsigned int lf = ___UNICODE_LINEFEED10; | |||
8250 | lineeditor_history *probe = d->hist_last->next; | |||
8251 | ||||
8252 | while (probe != d->hist_last) | |||
8253 | { | |||
8254 | if ((e = extensible_string_insert_at_end | |||
8255 | (&hist, | |||
8256 | probe->actual.length, | |||
8257 | probe->actual.buffer)) | |||
8258 | != ___FIX(___NO_ERR)(((long)(0))<<2) || | |||
8259 | (e = extensible_string_insert_at_end | |||
8260 | (&hist, | |||
8261 | 1, | |||
8262 | &lf)) | |||
8263 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8264 | break; | |||
8265 | ||||
8266 | probe = probe->next; | |||
8267 | } | |||
8268 | ||||
8269 | if (e != ___FIX(___NO_ERR)(((long)(0))<<2) || | |||
8270 | (e = extensible_string_insert_at_end | |||
8271 | (&hist, | |||
8272 | 1, | |||
8273 | &nul)) | |||
8274 | != ___FIX(___NO_ERR)(((long)(0))<<2) || | |||
8275 | (e = ___NONNULLSTRING_to_SCMOBJ | |||
8276 | (hist.buffer, | |||
8277 | &result, | |||
8278 | ___RETURN_POS127, | |||
8279 | ___CE(___C_CE_SELECT)(16<<0))) | |||
8280 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8281 | result = e; | |||
8282 | ||||
8283 | extensible_string_cleanup (&hist); | |||
8284 | } | |||
8285 | ||||
8286 | return result; | |||
8287 | } | |||
8288 | ||||
8289 | ||||
8290 | ___SCMOBJlong ___os_device_tty_history_set | |||
8291 | ___P((___SCMOBJ dev,(long dev, long history) | |||
8292 | ___SCMOBJ history),(long dev, long history) | |||
8293 | (dev,(long dev, long history) | |||
8294 | history)(long dev, long history) | |||
8295 | ___SCMOBJ dev;(long dev, long history) | |||
8296 | ___SCMOBJ history;)(long dev, long history) | |||
8297 | { | |||
8298 | ___device_tty *d = | |||
8299 | ___CAST(___device_tty*,___FIELD(dev,___FOREIGN_PTR))((___device_tty*)((*((((long*)((dev)-(1)))+1)+2)))); | |||
8300 | ___SCMOBJlong e; | |||
8301 | void *hist; | |||
8302 | ||||
8303 | if ((e = ___SCMOBJ_to_NONNULLSTRING | |||
8304 | (history, | |||
8305 | &hist, | |||
8306 | 1, | |||
8307 | ___CE(___C_CE_SELECT)(16<<0), | |||
8308 | 0)) | |||
8309 | == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8310 | { | |||
8311 | ___Cunsigned int *h = ___CAST(___C*,hist)((unsigned int*)(hist)); | |||
8312 | ||||
8313 | lineeditor_history_trim_to (d, 0); | |||
8314 | ||||
8315 | while (*h != ___UNICODE_NUL0) | |||
8316 | { | |||
8317 | ___Cunsigned int *start = h; | |||
8318 | ||||
8319 | while (*h != ___UNICODE_NUL0 && *h != ___UNICODE_LINEFEED10) | |||
8320 | h++; | |||
8321 | ||||
8322 | if (h != start) | |||
8323 | if ((e = lineeditor_history_add_line_before_last | |||
8324 | (d, | |||
8325 | h-start, | |||
8326 | start)) | |||
8327 | != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8328 | break; | |||
8329 | ||||
8330 | if (*h == ___UNICODE_LINEFEED10) | |||
8331 | h++; | |||
8332 | } | |||
8333 | ||||
8334 | lineeditor_history_trim (d); | |||
8335 | ||||
8336 | ___release_string (hist); | |||
8337 | } | |||
8338 | ||||
8339 | return e; | |||
8340 | } | |||
8341 | ||||
8342 | ||||
8343 | ___SCMOBJlong ___os_device_tty_history_max_length_set | |||
8344 | ___P((___SCMOBJ dev,(long dev, long max_length) | |||
8345 | ___SCMOBJ max_length),(long dev, long max_length) | |||
8346 | (dev,(long dev, long max_length) | |||
8347 | max_length)(long dev, long max_length) | |||
8348 | ___SCMOBJ dev;(long dev, long max_length) | |||
8349 | ___SCMOBJ max_length;)(long dev, long max_length) | |||
8350 | { | |||
8351 | ___device_tty *d = | |||
8352 | ___CAST(___device_tty*,___FIELD(dev,___FOREIGN_PTR))((___device_tty*)((*((((long*)((dev)-(1)))+1)+2)))); | |||
8353 | ||||
8354 | lineeditor_set_history_max_length (d, ___INT(max_length)((max_length)>>2)); | |||
8355 | ||||
8356 | return ___VOID((((long)(-5))<<2)+2); | |||
8357 | } | |||
8358 | ||||
8359 | ||||
8360 | ___SCMOBJlong ___os_device_tty_paren_balance_duration_set | |||
8361 | ___P((___SCMOBJ dev,(long dev, long duration) | |||
8362 | ___SCMOBJ duration),(long dev, long duration) | |||
8363 | (dev,(long dev, long duration) | |||
8364 | duration)(long dev, long duration) | |||
8365 | ___SCMOBJ dev;(long dev, long duration) | |||
8366 | ___SCMOBJ duration;)(long dev, long duration) | |||
8367 | { | |||
8368 | ___device_tty *d = | |||
8369 | ___CAST(___device_tty*,___FIELD(dev,___FOREIGN_PTR))((___device_tty*)((*((((long*)((dev)-(1)))+1)+2)))); | |||
8370 | int duration_nsecs = ___CAST(int,___FLONUM_VAL(duration) * 1e9)((int)(*((double*)((((long*)((duration)-(1)))+1))) * 1e9)); | |||
8371 | ||||
8372 | if (duration_nsecs < 0) | |||
8373 | duration_nsecs = 0; | |||
8374 | ||||
8375 | d->paren_balance_duration_nsecs = duration_nsecs; | |||
8376 | ||||
8377 | return ___VOID((((long)(-5))<<2)+2); | |||
8378 | } | |||
8379 | ||||
8380 | ||||
8381 | ___SCMOBJlong ___os_device_tty_mode_set | |||
8382 | ___P((___SCMOBJ dev,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8383 | ___SCMOBJ input_allow_special,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8384 | ___SCMOBJ input_echo,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8385 | ___SCMOBJ input_raw,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8386 | ___SCMOBJ output_raw,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8387 | ___SCMOBJ speed),(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8388 | (dev,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8389 | input_allow_special,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8390 | input_echo,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8391 | input_raw,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8392 | output_raw,(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8393 | speed)(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8394 | ___SCMOBJ dev;(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8395 | ___SCMOBJ input_allow_special;(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8396 | ___SCMOBJ input_echo;(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8397 | ___SCMOBJ input_raw;(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8398 | ___SCMOBJ output_raw;(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8399 | ___SCMOBJ speed;)(long dev, long input_allow_special, long input_echo, long input_raw , long output_raw, long speed) | |||
8400 | { | |||
8401 | ___device_tty *d = | |||
8402 | ___CAST(___device_tty*,___FIELD(dev,___FOREIGN_PTR))((___device_tty*)((*((((long*)((dev)-(1)))+1)+2)))); | |||
8403 | ___SCMOBJlong e; | |||
8404 | ||||
8405 | if ((e = ___device_tty_force_open (d)) == ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8406 | e = ___device_tty_mode_set | |||
8407 | (d, | |||
8408 | !___FALSEP(input_allow_special)((input_allow_special)==((((long)(-1))<<2)+2)), | |||
8409 | !___FALSEP(input_echo)((input_echo)==((((long)(-1))<<2)+2)), | |||
8410 | !___FALSEP(input_raw)((input_raw)==((((long)(-1))<<2)+2)), | |||
8411 | !___FALSEP(output_raw)((output_raw)==((((long)(-1))<<2)+2)), | |||
8412 | ___INT(speed)((speed)>>2)); | |||
8413 | ||||
8414 | return e; | |||
8415 | } | |||
8416 | ||||
8417 | ||||
8418 | #ifdef USE_POSIX | |||
8419 | ||||
8420 | ||||
8421 | void tty_signal_handler (int sig) | |||
8422 | { | |||
8423 | #ifdef USE_signal | |||
8424 | ___set_signal_handler (sig, tty_signal_handler); | |||
8425 | #endif | |||
8426 | ||||
8427 | switch (sig) | |||
8428 | { | |||
8429 | case SIGINT2: | |||
8430 | ___tty_mod.user_interrupt_handler (); | |||
8431 | break; | |||
8432 | ||||
8433 | case SIGTERM15: | |||
8434 | ___tty_mod.terminate_interrupt_handler (); | |||
8435 | break; | |||
8436 | ||||
8437 | case SIGWINCH28: | |||
8438 | { | |||
8439 | ___device_tty *probe = ___tty_mod.mode_save_stack; | |||
8440 | ||||
8441 | while (probe != NULL((void*)0)) | |||
8442 | { | |||
8443 | probe->size_needs_update = 1; | |||
8444 | probe = probe->mode_save_stack_next; | |||
8445 | } | |||
8446 | ||||
8447 | break; | |||
8448 | } | |||
8449 | ||||
8450 | case SIGCONT18: | |||
8451 | ___device_tty_mode_restore (0, 0); /***************/ | |||
8452 | break; | |||
8453 | } | |||
8454 | } | |||
8455 | ||||
8456 | ||||
8457 | #endif | |||
8458 | ||||
8459 | ||||
8460 | #ifdef USE_WIN32 | |||
8461 | ||||
8462 | ||||
8463 | ___HIDDENstatic BOOL WINAPI console_event_handler | |||
8464 | ___P((DWORD dwCtrlType),(DWORD dwCtrlType) | |||
8465 | (dwCtrlType)(DWORD dwCtrlType) | |||
8466 | DWORD dwCtrlType;)(DWORD dwCtrlType) | |||
8467 | { | |||
8468 | switch (dwCtrlType) | |||
8469 | { | |||
8470 | case CTRL_CLOSE_EVENT: | |||
8471 | case CTRL_LOGOFF_EVENT: | |||
8472 | case CTRL_SHUTDOWN_EVENT: | |||
8473 | ___tty_mod.terminate_interrupt_handler (); | |||
8474 | break; | |||
8475 | case CTRL_C_EVENT: | |||
8476 | case CTRL_BREAK_EVENT: | |||
8477 | ___tty_mod.user_interrupt_handler (); | |||
8478 | break; | |||
8479 | } | |||
8480 | ||||
8481 | SetEvent (___io_mod.abort_select); /* ignore error */ | |||
8482 | ||||
8483 | return TRUE; | |||
8484 | ||||
8485 | #if 0 | |||
8486 | #if 0 | |||
8487 | /**********************************/ | |||
8488 | switch (dwCtrlType) | |||
8489 | { | |||
8490 | case CTRL_C_EVENT: | |||
8491 | io_mod.got_event = 1; | |||
8492 | break; | |||
8493 | case CTRL_BREAK_EVENT: | |||
8494 | io_mod.got_event = 2; | |||
8495 | break; | |||
8496 | case CTRL_CLOSE_EVENT: | |||
8497 | io_mod.got_event = 3; | |||
8498 | break; | |||
8499 | case CTRL_LOGOFF_EVENT: | |||
8500 | io_mod.got_event = 4; | |||
8501 | break; | |||
8502 | case CTRL_SHUTDOWN_EVENT: | |||
8503 | io_mod.got_event = 5; | |||
8504 | break; | |||
8505 | default: | |||
8506 | io_mod.got_event = 999; | |||
8507 | } | |||
8508 | ||||
8509 | SetEvent (io_mod.abort_select); /* ignore error */ | |||
8510 | ||||
8511 | return TRUE; | |||
8512 | #else | |||
8513 | return FALSE; | |||
8514 | #endif | |||
8515 | #endif | |||
8516 | } | |||
8517 | ||||
8518 | ||||
8519 | #endif | |||
8520 | ||||
8521 | ||||
8522 | ___SCMOBJlong ___setup_user_interrupt_handling ___PVOID(void) | |||
8523 | { | |||
8524 | #ifdef USE_POSIX | |||
8525 | ||||
8526 | ___set_signal_handler (SIGINT2, tty_signal_handler); | |||
8527 | ___set_signal_handler (SIGTERM15, tty_signal_handler); | |||
8528 | ___set_signal_handler (SIGWINCH28, tty_signal_handler); | |||
8529 | ___set_signal_handler (SIGCONT18, tty_signal_handler); | |||
8530 | ||||
8531 | #endif | |||
8532 | ||||
8533 | #ifdef USE_WIN32 | |||
8534 | ||||
8535 | SetConsoleCtrlHandler (console_event_handler, TRUE); /* ignore error */ | |||
8536 | ||||
8537 | #endif | |||
8538 | ||||
8539 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
8540 | } | |||
8541 | ||||
8542 | ||||
8543 | void ___cleanup_user_interrupt_handling ___PVOID(void) | |||
8544 | { | |||
8545 | #ifdef USE_POSIX | |||
8546 | ||||
8547 | ___set_signal_handler (SIGINT2, SIG_DFL((__sighandler_t) 0)); | |||
8548 | ___set_signal_handler (SIGTERM15, SIG_DFL((__sighandler_t) 0)); | |||
8549 | ___set_signal_handler (SIGWINCH28, SIG_DFL((__sighandler_t) 0)); | |||
8550 | ___set_signal_handler (SIGCONT18, SIG_DFL((__sighandler_t) 0)); | |||
8551 | ||||
8552 | #endif | |||
8553 | ||||
8554 | #ifdef USE_WIN32 | |||
8555 | ||||
8556 | SetConsoleCtrlHandler (console_event_handler, FALSE); /* ignore error */ | |||
8557 | ||||
8558 | #endif | |||
8559 | } | |||
8560 | ||||
8561 | ||||
8562 | void ___disable_user_interrupts ___PVOID(void) | |||
8563 | { | |||
8564 | #ifdef USE_POSIX | |||
8565 | #ifdef HAVE_SIGPROCMASK1 | |||
8566 | ||||
8567 | sigset_t sigs; | |||
8568 | ||||
8569 | sigemptyset (&sigs); | |||
8570 | sigaddset (&sigs, SIGINT2); | |||
8571 | sigaddset (&sigs, SIGTERM15); | |||
8572 | sigaddset (&sigs, SIGWINCH28); | |||
8573 | sigaddset (&sigs, SIGCONT18); | |||
8574 | ||||
8575 | sigprocmask (SIG_BLOCK0, &sigs, NULL((void*)0)); | |||
8576 | ||||
8577 | #endif | |||
8578 | #endif | |||
8579 | } | |||
8580 | ||||
8581 | void ___enable_user_interrupts ___PVOID(void) | |||
8582 | { | |||
8583 | #ifdef USE_POSIX | |||
8584 | #ifdef HAVE_SIGPROCMASK1 | |||
8585 | ||||
8586 | sigset_t sigs; | |||
8587 | ||||
8588 | sigemptyset (&sigs); | |||
8589 | sigaddset (&sigs, SIGINT2); | |||
8590 | sigaddset (&sigs, SIGTERM15); | |||
8591 | sigaddset (&sigs, SIGWINCH28); | |||
8592 | sigaddset (&sigs, SIGCONT18); | |||
8593 | ||||
8594 | sigprocmask (SIG_UNBLOCK1, &sigs, NULL((void*)0)); | |||
8595 | ||||
8596 | #endif | |||
8597 | #endif | |||
8598 | } | |||
8599 | ||||
8600 | ||||
8601 | ___SCMOBJlong ___setup_tty_module | |||
8602 | ___P((void (*user_interrupt_handler) ___PVOID,(void (*user_interrupt_handler) (void), void (*terminate_interrupt_handler ) (void)) | |||
8603 | void (*terminate_interrupt_handler) ___PVOID),(void (*user_interrupt_handler) (void), void (*terminate_interrupt_handler ) (void)) | |||
8604 | (user_interrupt_handler,(void (*user_interrupt_handler) (void), void (*terminate_interrupt_handler ) (void)) | |||
8605 | terminate_interrupt_handler)(void (*user_interrupt_handler) (void), void (*terminate_interrupt_handler ) (void)) | |||
8606 | void (*user_interrupt_handler) ___PVOID;(void (*user_interrupt_handler) (void), void (*terminate_interrupt_handler ) (void)) | |||
8607 | void (*terminate_interrupt_handler) ___PVOID;)(void (*user_interrupt_handler) (void), void (*terminate_interrupt_handler ) (void)) | |||
8608 | { | |||
8609 | if (___tty_mod.refcount == 0) | |||
8610 | { | |||
8611 | ___SCMOBJlong e; | |||
8612 | ||||
8613 | ___tty_mod.mode_save_stack = NULL((void*)0); | |||
8614 | ||||
8615 | ___tty_mod.user_interrupt_handler = user_interrupt_handler; | |||
8616 | ||||
8617 | ___tty_mod.terminate_interrupt_handler = terminate_interrupt_handler; | |||
8618 | ||||
8619 | if ((e = ___setup_user_interrupt_handling ()) != ___FIX(___NO_ERR)(((long)(0))<<2)) | |||
8620 | return e; | |||
8621 | } | |||
8622 | ||||
8623 | ___tty_mod.refcount++; | |||
8624 | ||||
8625 | return ___FIX(___NO_ERR)(((long)(0))<<2); | |||
8626 | } | |||
8627 | ||||
8628 | ||||
8629 | void ___cleanup_tty_module ___PVOID(void) | |||
8630 | { | |||
8631 | /********************* on Win32 this should be an InterlockedDecrement */ | |||
8632 | if (--___tty_mod.refcount == 0) | |||
8633 | { | |||
8634 | ___cleanup_user_interrupt_handling (); | |||
8635 | } | |||
8636 | } |