File: | os_tty.c |
Location: | line 5711, column 9 |
Description: | Value stored to 'e' is never read |
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); |
Value stored to 'e' is never read | |
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 | } |