source: trunk/essentials/sys-apps/texinfo/info/pcterm.c

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

GNU Texinfo 4.8

File size: 21.7 KB
Line 
1/* pcterm.c -- How to handle the PC terminal for Info under MS-DOS/MS-Windows.
2 $Id: pcterm.c,v 1.4 2004/04/11 17:56:46 karl Exp $
3
4 Copyright (C) 1998, 1999, 2003, 2004 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20
21/* WARNING WARNING WARNING!!!
22 This probably won't work as is with anything but DJGPP! However, Borland
23 should come close, and other PC compilers will need minor modifications. */
24
25/* intl/libintl.h defines a macro `gettext' which
26 conflicts with conio.h header. */
27#ifdef gettext
28# undef gettext
29# define gettext _gettext
30#endif
31
32#include <pc.h>
33#include <keys.h>
34#include <conio.h>
35
36#include "variables.h"
37
38extern int speech_friendly; /* defined in info.c */
39
40/* **************************************************************** */
41/* */
42/* PC Terminal Output Functions */
43/* */
44/* **************************************************************** */
45
46static struct text_info outside_info; /* holds screen params outside Info */
47static unsigned char norm_attr, inv_attr;
48
49static unsigned const char * find_sequence (int);
50
51/* Turn on reverse video. */
52static void
53pc_begin_inverse (void)
54{
55 textattr (inv_attr);
56}
57
58/* Turn off reverse video. */
59static void
60pc_end_inverse (void)
61{
62 textattr (norm_attr);
63}
64
65/* Move the cursor up one line. */
66static void
67pc_up_line (void)
68{
69 int x, y;
70 ScreenGetCursor (&y, &x);
71 ScreenSetCursor (MAX (y-1, 0), x);
72}
73
74/* Move the cursor down one line. */
75static void
76pc_down_line (void)
77{
78 int x, y;
79 ScreenGetCursor (&y, &x);
80 ScreenSetCursor (MIN (screenheight-1, y+1), x);
81}
82
83/* Clear the entire terminal screen. */
84static void
85pc_clear_screen (void)
86{
87 ScreenClear ();
88}
89
90/* Clear from the current position of the cursor to the end of the line. */
91static void
92pc_clear_to_eol (void)
93{
94 clreol (); /* perhaps to be replaced by a loop */
95}
96
97/* Set the global variables SCREENWIDTH and SCREENHEIGHT. */
98static void
99pc_get_screen_size(void)
100{
101 /* Current screen dimensions are the default. */
102 if (!outside_info.screenheight) /* paranoia */
103 gettextinfo (&outside_info);
104 screenwidth = outside_info.screenwidth;
105 screenheight = outside_info.screenheight;
106
107 /* Environment variable "LINES" overrides the default. */
108 if (getenv ("LINES") != NULL)
109 screenheight = atoi (getenv ("LINES"));
110
111 /* Environment variable "INFO_LINES" overrides "LINES". */
112 if (getenv ("INFO_LINES") != NULL)
113 screenheight = atoi (getenv ("INFO_LINES"));
114}
115
116/* Move the cursor to the terminal location of X and Y. */
117static void
118pc_goto_xy (x, y)
119 int x, y;
120{
121 ScreenSetCursor (y, x); /* yes, pc.h says ScreenSetCursor (row, column) !! */
122}
123
124/* Print STRING to the terminal at the current position. */
125static void
126pc_put_text (string)
127 char *string;
128{
129 if (speech_friendly)
130 fputs (string, stdout);
131 else
132 cputs (string);
133}
134
135/* Ring the terminal bell. The bell is rung visibly if the terminal is
136 capable of doing that, and if terminal_use_visible_bell_p is non-zero. */
137static void
138pc_ring_bell(void)
139{
140 if (terminal_has_visible_bell_p && terminal_use_visible_bell_p)
141 ScreenVisualBell ();
142 else
143 {
144 printf ("%c",'\a');
145 fflush (stdout);
146 }
147}
148
149/* Print NCHARS from STRING to the terminal at the current position. */
150static void
151pc_write_chars (string, nchars)
152 char *string;
153 int nchars;
154{
155 if (!nchars)
156 return;
157
158 if (speech_friendly)
159 printf ("%.*s",nchars, string);
160 else
161 cprintf ("%..*s",nchars, string);
162}
163
164/* Scroll an area of the terminal from START to (and excluding) END,
165 AMOUNT lines. If AMOUNT is negative, the lines are scrolled
166 towards the top of the screen, else they are scrolled towards the
167 bottom of the screen. The lines of the old region which do not
168 overlap the new region are cleared, to mimic terminal operation. */
169static void
170pc_scroll_terminal (start, end, amount)
171 int start, end, amount;
172{
173 int line_to_clear = amount > 0 ? start : end + amount;
174
175 /* Move the text. Note that `movetext' expects 1-based coordinates. */
176 movetext (1, start + 1, ScreenCols (), end, 1, start + amount + 1);
177
178 /* Now clear the lines which were left unoccupied. */
179 if (amount < 0)
180 amount = -amount;
181 while (amount--)
182 {
183 ScreenSetCursor (line_to_clear++, 0);
184 clreol ();
185 }
186}
187
188/* Put the screen in the video mode and colors which Info will use.
189 Prepare to start using the terminal to read characters singly. */
190static void
191pc_prep_terminal (void)
192{
193 int tty;
194
195 /* Do not set screen height if we already have it, because
196 doing so erases the screen. */
197 if (screenheight != ScreenRows ())
198 _set_screen_lines (screenheight);
199
200 /* Don't fail if they asked for screen dimensions that their
201 hardware cannot support. */
202 screenheight = ScreenRows ();
203 screenwidth = ScreenCols ();
204
205 /* Try setting the colors user asked for. */
206 textattr (norm_attr);
207 ScreenClear ();
208
209 /* Switch console reads to binary mode. */
210 tty = fileno (stdin);
211#ifdef __DJGPP__
212 setmode (tty, O_BINARY);
213 __djgpp_set_ctrl_c (1); /* re-enable SIGINT generation by Ctrl-C */
214#endif
215}
216
217/* Restore the tty settings back to what they were before we started using
218 this terminal. */
219static void
220pc_unprep_terminal (void)
221{
222 int tty;
223
224 textattr (outside_info.normattr);
225
226 /* Do not set screen height if we already have it, because
227 doing so erases the screen. */
228 if (outside_info.screenheight != ScreenRows ())
229 {
230 _set_screen_lines (outside_info.screenheight);
231 textmode (LASTMODE);
232 }
233 else
234 pc_clear_to_eol (); /* for text attributes to really take effect */
235
236 /* Switch back to text mode on stdin. */
237 tty = fileno (stdin);
238#ifdef __DJGPP__
239 setmode (tty, O_TEXT);
240#endif
241}
242
243/* Initialize the terminal which is known as TERMINAL_NAME. If this
244 terminal doesn't have cursor addressability, `terminal_is_dumb_p'
245 becomes nonzero. The variables SCREENHEIGHT and SCREENWIDTH are set
246 to the dimensions that this terminal actually has. The variable
247 TERMINAL_HAS_META_P becomes nonzero if this terminal supports a Meta
248 key. Finally, the terminal screen is cleared. */
249static void
250pc_initialize_terminal (term_name)
251 char *term_name;
252{
253 char *info_colors;
254
255 if (!term_name)
256 {
257 term_name = getenv ("TERM");
258 if (!term_name)
259 term_name = "pc-dos"; /* ``what's in a name?'' */
260 }
261
262 /* Get current video information, to be restored later. */
263 if (outside_info.screenwidth == 0)
264 gettextinfo (&outside_info);
265
266 /* Current screen colors are the default. */
267 norm_attr = outside_info.normattr;
268 inv_attr = (((outside_info.normattr & 7) << 4) |
269 ((outside_info.normattr & 0x7f) >> 4));
270
271 /* Does the user want non-default colors? */
272 info_colors = getenv ("INFO_COLORS");
273 if ((info_colors != (char *)0) && !speech_friendly)
274 {
275 /* Decode a color from a string descriptor.
276 The descriptor string is a sequence of color specifiers separated
277 by a non-numeric character. Each color specifier should represent
278 a small integer which fits into an unsigned char, and can be given
279 in any base supported by strtoul. Examples of valid descriptors:
280
281 "10 31"
282 "0x13/0x45"
283 "007.077"
284
285 The separator between two color specifiers can be any character which
286 cannot be used in a printed representation of an integer number. */
287 char *endp;
288 unsigned long color_desc = strtoul (info_colors, &endp, 0);
289
290 if (color_desc <= UCHAR_MAX)
291 {
292 norm_attr = (unsigned char)color_desc;
293 color_desc = strtoul (endp + 1, &endp, 0);
294 if (color_desc <= UCHAR_MAX)
295 inv_attr = (unsigned char)color_desc;
296 }
297 }
298
299 /* We can scroll. */
300 terminal_can_scroll = 1;
301
302 /* We know how to produce a visible bell, if somebody's looking... */
303 if (!speech_friendly)
304 terminal_has_visible_bell_p = 1;
305
306 /* We have a Meta key. */
307 terminal_has_meta_p = 1;
308
309 /* We are *certainly* NOT dumb! */
310 terminal_is_dumb_p = 0;
311
312 pc_get_screen_size ();
313
314 /* Store the arrow keys. */
315 term_ku = (char *)find_sequence (K_Up);
316 term_kd = (char *)find_sequence (K_Down);
317 term_kr = (char *)find_sequence (K_Right);
318 term_kl = (char *)find_sequence (K_Left);
319
320 term_kP = (char *)find_sequence (K_PageUp);
321 term_kN = (char *)find_sequence (K_PageDown);
322
323#if defined(INFOKEY)
324 term_kh = (char *)find_sequence (K_Home);
325 term_ke = (char *)find_sequence (K_End);
326 term_ki = (char *)find_sequence (K_Insert);
327 term_kx = (char *)find_sequence (K_Delete);
328#endif
329
330 /* Set all the hooks to our PC-specific functions. */
331 terminal_begin_inverse_hook = pc_begin_inverse;
332 terminal_end_inverse_hook = pc_end_inverse;
333 terminal_prep_terminal_hook = pc_prep_terminal;
334 terminal_unprep_terminal_hook = pc_unprep_terminal;
335 terminal_up_line_hook = pc_up_line;
336 terminal_down_line_hook = pc_down_line;
337 terminal_clear_screen_hook = pc_clear_screen;
338 terminal_clear_to_eol_hook = pc_clear_to_eol;
339 terminal_get_screen_size_hook = pc_get_screen_size;
340 terminal_goto_xy_hook = pc_goto_xy;
341 terminal_put_text_hook = pc_put_text;
342 terminal_ring_bell_hook = pc_ring_bell;
343 terminal_write_chars_hook = pc_write_chars;
344 terminal_scroll_terminal_hook = pc_scroll_terminal;
345}
346
347
348/* **************************************************************** */
349/* */
350/* How to Read Characters From the PC Terminal */
351/* */
352/* **************************************************************** */
353
354/* This will most certainly work ONLY with DJGPP. */
355#ifdef __DJGPP__
356
357#include <errno.h>
358#include <sys/fsext.h>
359#include <dpmi.h>
360
361/* Translation table for some special keys.
362 Arrow keys which are standard on other keyboards are translated into
363 standard ESC-sequences, in case somebody rebinds the simple keys
364 (like C-f, C-b, C-n, etc.).
365
366 The strange "\033\061" prefix in some keys is a numeric argument of
367 one, which means ``do the next command once''. It is here so that
368 when the according PC key is pressed in the middle of an incremental
369 search, Info doesn't see just an ASCII character like `n' or `B',
370 and doesn't add it to the search string; instead, it will exit the
371 incremental search and then perform the command. */
372static struct
373{
374 int inkey;
375 unsigned char const * const sequence;
376} DJGPP_keytab[] = { /* these are for moving between nodes... */
377 {K_Control_PageDown, "\033\061n"},
378 {K_Control_PageUp, "\033\061p"},
379 {K_Control_Up, "\033\061u"},
380 {K_Control_Down, "\033\061m"},
381 {K_Control_Center, "\033\061l"},
382
383#if defined(INFOKEY)
384 {K_Home, "\033[H"}, /* ...and these are for moving IN a node */
385 {K_End, "\033[F"}, /* they're Numeric-Keypad-Keys, so */
386#else
387 {K_Home, "\001"},
388 {K_End, "\005"},
389#endif
390 {K_Left, "\033[D"}, /* NUMLOCK should be off !! */
391 {K_Right, "\033[C"},
392 {K_Down, "\033[B"},
393 {K_Up, "\033[A"},
394 {K_PageDown, "\033[G"},
395 {K_PageUp, "\033[I"},
396 {K_Control_Left, "\033b"},
397 {K_Control_Right, "\033f"},
398 {K_Control_Home, "\033<"},
399 {K_Control_End, "\033>"},
400
401#if defined(INFOKEY)
402 {K_EHome, "\033[H"}, /* these are also for moving IN a node */
403 {K_EEnd, "\033[F"}, /* they're the "extended" (Grey) keys */
404#else
405 {K_EHome, "\001"},
406 {K_EEnd, "\005"},
407#endif
408 {K_ELeft, "\033[D"},
409 {K_ERight, "\033[C"},
410 {K_EDown, "\033[B"},
411 {K_EUp, "\033[A"},
412 {K_EPageDown, "\033[G"},
413 {K_EPageUp, "\033[I"},
414 {K_Control_ELeft, "\033b"},
415 {K_Control_ERight, "\033f"},
416 {K_Control_EHome, "\033<"},
417 {K_Control_EEnd, "\033>"},
418
419 {K_BackTab, "\033\011"},
420 {K_F1, "\10"}, /* YEAH, gimme that good old F-one-thing */
421 {K_Delete, "\177"}, /* to make Kp-Del be DEL (0x7f) */
422 {K_EDelete, "\177"}, /* to make Delete be DEL (0x7f) */
423#if defined(INFOKEY)
424 {K_Insert, "\033[L"},
425 {K_EInsert, "\033[L"},
426#endif
427
428 /* These are here to map more Alt-X keys to ESC X sequences. */
429 {K_Alt_Q, "\033q"},
430 {K_Alt_W, "\033w"},
431 {K_Alt_E, "\033e"},
432 {K_Alt_R, "\033r"},
433 {K_Alt_T, "\033t"},
434 {K_Alt_Y, "\033y"},
435 {K_Alt_U, "\033u"},
436 {K_Alt_I, "\033i"},
437 {K_Alt_O, "\033o"},
438 {K_Alt_P, "\033p"},
439 {K_Alt_LBracket, "\033["},
440 {K_Alt_RBracket, "\033]"},
441 {K_Alt_Return, "\033\015"},
442 {K_Alt_A, "\033a"},
443 {K_Alt_S, "\033s"},
444 {K_Alt_D, "\033d"},
445 {K_Alt_F, "\033f"},
446 {K_Alt_G, "\033g"},
447 {K_Alt_H, "\033h"},
448 {K_Alt_J, "\033j"},
449 {K_Alt_K, "\033k"},
450 {K_Alt_L, "\033l"},
451 {K_Alt_Semicolon, "\033;"},
452 {K_Alt_Quote, "\033'"},
453 {K_Alt_Backquote, "\033`"},
454 {K_Alt_Backslash, "\033\\"},
455 {K_Alt_Z, "\033z"},
456 {K_Alt_X, "\033x"},
457 {K_Alt_C, "\033c"},
458 {K_Alt_V, "\033v"},
459 {K_Alt_B, "\033b"},
460 {K_Alt_N, "\033n"},
461 {K_Alt_M, "\033m"},
462 {K_Alt_Comma, "\033<"}, /* our reader cannot distinguish between */
463 {K_Alt_Period, "\033>"}, /* Alt-. and Alt->, so we cheat a little */
464 {K_Alt_Slash, "\033?"}, /* ditto, to get Alt-? */
465 {K_Alt_Backspace, "\033\177"}, /* M-DEL, to delete word backwards */
466 {K_Alt_1, "\033\061"},
467 {K_Alt_2, "\033\062"},
468 {K_Alt_3, "\033\063"},
469 {K_Alt_4, "\033\064"},
470 {K_Alt_5, "\033\065"},
471 {K_Alt_6, "\033\066"},
472 {K_Alt_7, "\033\067"},
473 {K_Alt_8, "\033\070"},
474 {K_Alt_9, "\033\071"},
475 {K_Alt_0, "\033\060"},
476 {K_Alt_Dash, "\033\055"},
477 {K_Alt_EPageUp, "\033\033[I"},
478 {K_Alt_EPageDown, "\033\033[G"},
479 {K_Alt_Equals, "\033\075"},
480 {K_Alt_EDelete, "\033\177"},
481 {K_Alt_Tab, "\033\011"},
482 {0, 0}
483};
484
485/* Given a key, return the sequence of characters which
486 our keyboard driver generates. */
487static unsigned const char *
488find_sequence (int key)
489{
490 int i;
491
492 for (i = 0; DJGPP_keytab[i].inkey; i++)
493 if (key == DJGPP_keytab[i].inkey)
494 return DJGPP_keytab[i].sequence;
495
496 return (unsigned const char *)NULL;
497}
498
499/* Return zero if a key is pending in the
500 keyboard buffer, non-zero otherwise. */
501static int
502kbd_buffer_empty (void)
503{
504 __dpmi_regs r;
505 int retval;
506
507 r.h.ah = 0x11; /* Get enhanced keyboard status */
508 __dpmi_int (0x16, &r);
509
510 /* If the keyboard buffer is empty, the Zero Flag will be set. */
511 return (r.x.flags & 0x40) == 0x40;
512}
513
514/* The buffered characters pending to be read.
515 Actually, Info usually reads a single character, but when we
516 translate a key into a sequence of characters, we keep them here. */
517static unsigned char buffered[512];
518
519/* Index of the next buffered character to be returned. */
520static int buf_idx;
521
522/* Return the number of characters waiting to be read. */
523long
524pc_term_chars_avail (void)
525{
526 if (buf_idx >= sizeof (buffered)) /* paranoia */
527 {
528 buf_idx = 0;
529 buffered[buf_idx] = '\0';
530 return 0;
531 }
532 else
533 return (long)strlen (buffered + buf_idx);
534}
535
536/* Our special terminal keyboard reader. It will be called by
537 low-level libc functions when the application calls `read' or
538 the ANSI-standard stream-oriented read functions. If the
539 caller wants to read the terminal, we redirect the call to
540 the BIOS keyboard functions, since that lets us recognize more
541 keys than DOS does. */
542static int
543keyboard_read (__FSEXT_Fnumber func, int *retval, va_list rest_args)
544{
545 /* When we are called, REST_ARGS are: file_descriptor, buf, nbytes. */
546 unsigned char *buf;
547 size_t nbytes, nread = 0;
548 int fd = va_arg (rest_args, int);
549
550 /* Is this call for us? */
551 if (func != __FSEXT_read || !isatty (fd))
552 return 0; /* and the usual DOS call will be issued */
553
554 buf = va_arg (rest_args, unsigned char *);
555 nbytes = va_arg (rest_args, size_t);
556
557 if (!buf)
558 {
559 errno = EINVAL;
560 *retval = -1;
561 return 1;
562 }
563 if (!nbytes)
564 {
565 *retval = 0;
566 return 1;
567 }
568
569 /* Loop here until enough bytes has been read. */
570 do
571 {
572 int key;
573
574 /* If any ``buffered characters'' are left, return as much
575 of them as the caller wanted. */
576 while (buffered[buf_idx] && nbytes)
577 {
578 *buf++ = buffered[buf_idx++];
579 nread++;
580 nbytes--;
581 }
582
583 if (nbytes <= 0)
584 break;
585
586 /* Wait for another key.
587 We do that in a busy-waiting loop so we don't get parked
588 inside a BIOS call, which will effectively disable signals.
589 While we wait for them to type something, we repeatedly
590 release the rest of our time slice, so that other programs
591 in a multitasking environment, such as Windows, get more cycles. */
592 while (kbd_buffer_empty ())
593 __dpmi_yield ();
594
595 key = getxkey ();
596
597 /* Translate the key if necessary.
598 Untranslated non-ASCII keys are silently ignored. */
599 if ((key & 0x300) != 0)
600 {
601 unsigned char const * key_sequence = find_sequence (key);
602
603 if (key_sequence != NULL)
604 {
605 strcpy (buffered, key_sequence);
606 buf_idx = 0;
607 }
608 }
609 else if (key == K_Control_Z)
610 raise (SIGUSR1); /* we don't have SIGTSTP, so simulate it */
611 else if (key <= 0xff)
612 {
613 *buf++ = key;
614 nbytes--;
615 nread++;
616 }
617 }
618 while (nbytes > 0);
619
620 *retval = nread;
621 return 1; /* meaning that we handled the call */
622}
623
624/* Install our keyboard handler.
625 This is called by the startup code before `main'. */
626static void __attribute__((constructor))
627install_keyboard_handler (void)
628{
629 __FSEXT_set_function (fileno (stdin), keyboard_read);
630
631 /* We need to set this single hook here; the rest
632 will be set by pc_initialize_terminal when it is called. */
633 terminal_initialize_terminal_hook = pc_initialize_terminal;
634}
635
636#endif /* __DJGPP__ */
637
638
639/* **************************************************************** */
640/* */
641/* Emulation of SIGTSTP on Ctrl-Z */
642/* */
643/* **************************************************************** */
644
645#include <limits.h>
646#include "signals.h"
647#include "session.h"
648
649#ifndef PATH_MAX
650# define PATH_MAX 512
651#endif
652
653/* Effectively disable signals which aren't defined
654 (assuming no signal can ever be zero).
655 SIGINT is ANSI, so we expect it to be always defined. */
656#ifndef SIGUSR1
657# define SIGUSR1 0
658#endif
659#ifndef SIGQUIT
660# define SIGQUIT 0
661#endif
662
663int
664kill (pid_t pid, int sig)
665{
666 static char interrupted_msg[] = "Interrupted\r\n";
667 static char stopped_msg[] = "Stopped. Type `exit RET' to return.\r\n";
668 char cwd[PATH_MAX + 1];
669
670 if (pid == getpid ()
671 || pid == 0
672 || pid == -1
673 || pid == -getpid ())
674 {
675 switch (sig)
676 {
677 RETSIGTYPE (*old_INT)(int), (*old_QUIT)(int);
678
679 case SIGINT:
680#ifdef __DJGPP__
681 /* If SIGINT was generated by a readable key, we want to remove
682 it from the PC keyboard buffer, so that DOS and other
683 programs never see it. DJGPP signal-handling mechanism
684 doesn't remove the INT key from the keyboard buffer. */
685 if (!kbd_buffer_empty ())
686 getxkey ();
687#endif
688 pc_write_chars (interrupted_msg, sizeof (interrupted_msg) - 1);
689 xexit (1);
690 case SIGUSR1:
691 /* Simulate SIGTSTP by invoking a subsidiary shell. */
692 pc_goto_xy (0, outside_info.screenheight - 1);
693 pc_clear_to_eol ();
694 pc_write_chars (stopped_msg, sizeof (stopped_msg) - 1);
695
696 /* The child shell can change the working directory, so
697 we need to save and restore it, since it is global. */
698 if (!getcwd (cwd, PATH_MAX)) /* should never happen */
699 cwd[0] = '\0';
700
701 /* We don't want to get fatal signals while the subshell runs. */
702 old_INT = signal (SIGINT, SIG_IGN);
703 old_QUIT = signal (SIGQUIT, SIG_IGN);
704 system ("");
705 if (*cwd)
706 chdir (cwd);
707 signal (SIGINT, old_INT);
708 signal (SIGQUIT, old_QUIT);
709 break;
710 default:
711 if (sig)
712 raise (sig);
713 break;
714 }
715 return 0;
716 }
717 else
718 return -1;
719}
720
721
722/* These should never be called, but they make the linker happy. */
723
724void tputs (char *a, int b, int (*c)())
725{
726 perror ("tputs");
727}
728
729char* tgoto (char*a, int b, int c)
730{
731 perror ("tgoto"); return 0; /* here and below, added dummy retvals */
732}
733
734int tgetnum (char*a)
735{
736 perror ("tgetnum"); return 0;
737}
738
739int tgetflag (char*a)
740{
741 perror ("tgetflag"); return 0;
742}
743
744char* tgetstr (char *a, char **b)
745{
746 perror ("tgetstr"); return 0;
747}
748
749int tgetent (char*a, char*b)
750{
751 perror ("tgetent"); return 0;
752}
753
754int tcgetattr(int fildes, struct termios *termios_p)
755{
756 perror ("tcgetattr"); return 0;
757}
758
759int tcsetattr(int fd, int opt_actions, const struct termios *termios_p)
760{
761 perror ("tcsetattr"); return 0;
762}
Note: See TracBrowser for help on using the repository browser.