4 * Copyright (c) 2008 James McKenzie <sympathy@madingley.org>,
10 "$Id: terminal.c,v 1.24 2008/03/12 10:47:26 james Exp $";
13 * $Log: terminal.c,v $
14 * Revision 1.24 2008/03/12 10:47:26 james
17 * Revision 1.23 2008/03/12 01:30:23 james
18 * *** empty log message ***
20 * Revision 1.22 2008/03/11 17:56:50 james
21 * *** empty log message ***
23 * Revision 1.21 2008/03/11 17:56:04 james
24 * *** empty log message ***
26 * Revision 1.20 2008/03/10 11:49:33 james
27 * *** empty log message ***
29 * Revision 1.19 2008/03/07 14:16:44 james
30 * *** empty log message ***
32 * Revision 1.18 2008/03/07 14:13:40 james
33 * *** empty log message ***
35 * Revision 1.17 2008/03/07 13:16:02 james
36 * *** empty log message ***
38 * Revision 1.16 2008/03/07 12:42:08 james
39 * *** empty log message ***
41 * Revision 1.15 2008/03/07 12:37:04 james
42 * *** empty log message ***
44 * Revision 1.14 2008/03/03 06:04:42 james
45 * *** empty log message ***
47 * Revision 1.13 2008/03/02 10:37:56 james
48 * *** empty log message ***
50 * Revision 1.12 2008/02/28 16:57:52 james
51 * *** empty log message ***
53 * Revision 1.11 2008/02/26 23:56:12 james
54 * *** empty log message ***
56 * Revision 1.10 2008/02/26 23:23:17 james
57 * *** empty log message ***
59 * Revision 1.9 2008/02/15 03:32:07 james
60 * *** empty log message ***
62 * Revision 1.8 2008/02/14 10:39:14 james
63 * *** empty log message ***
65 * Revision 1.7 2008/02/14 01:55:57 james
66 * *** empty log message ***
68 * Revision 1.6 2008/02/14 00:57:58 james
69 * *** empty log message ***
71 * Revision 1.5 2008/02/13 18:05:06 james
72 * *** empty log message ***
74 * Revision 1.4 2008/02/13 16:57:29 james
75 * *** empty log message ***
77 * Revision 1.3 2008/02/13 09:12:21 james
78 * *** empty log message ***
80 * Revision 1.2 2008/02/13 01:08:18 james
81 * *** empty log message ***
83 * Revision 1.1 2008/02/12 22:36:46 james
84 * *** empty log message ***
86 * Revision 1.1 2008/02/09 15:47:28 james
87 * *** empty log message ***
89 * Revision 1.2 2008/02/07 11:11:14 staffcvs
90 * *** empty log message ***
92 * Revision 1.1 2008/02/07 01:02:52 james
93 * *** empty log message ***
95 * Revision 1.3 2008/02/06 17:53:28 james
96 * *** empty log message ***
98 * Revision 1.2 2008/02/04 02:05:06 james
99 * *** empty log message ***
101 * Revision 1.1 2008/02/04 01:32:39 james
102 * *** empty log message ***
109 typedef struct TERMINAL_struct {
111 struct termios orig_termios;
112 struct TERMINAL_struct *next;
116 static TERMINAL *terminal_list = NULL;
117 int terminal_winches;
122 terminal_close (TTY * _t)
127 TERMINAL *t = (TERMINAL *) _t;
128 TERMINAL **ptr = &terminal_list;
133 /* Take out of cleanup list */
134 while (*ptr && (*ptr != t))
135 ptr = &((*ptr)->next);
140 tcsetattr (t->wfd, TCSANOW, &t->orig_termios);
142 set_nonblocking (t->wfd);
145 t->xmit (_t, "\033%@", 3); // Leave UTF-8
146 t->xmit (_t, "\033(B", 3); // US-ASCII in G0
147 t->xmit (_t, "\033)B", 3); // US-ASCII in G1
148 t->xmit (_t, "\017", 1); // Select G0
149 t->xmit (_t, "\033[?25h", 6); // Show cursor
150 t->xmit (_t, "\033[r", 3); // No margins
151 t->xmit (_t, "\033[0m", 4); // Default attributes
152 i = sprintf (buf, "\033[%d;%dH", t->displayed_length ? (t->displayed_length + 1) : (CRT_ROWS + 1), 1);
154 t->xmit (_t, buf, i);
155 t->xmit (_t, "\033[J", 3); // erase rest of screen
157 set_blocking (t->rfd);
158 set_blocking (t->wfd);
165 terminal_atexit (void)
167 while (terminal_list)
168 terminal_close ((TTY *) terminal_list);
186 terminal_getsize (TTY * _t)
188 TERMINAL *t = (TERMINAL *) _t;
189 struct winsize sz = { 0 };
194 if (ioctl (t->wfd, TIOCGWINSZ, &sz)) {
195 t->size.x = CRT_COLS;
196 t->size.y = CRT_ROWS;
198 t->size.x = sz.ws_col;
199 t->size.y = sz.ws_row;
205 terminal_dispatch (void)
210 if (!terminal_winches)
213 terminal_winches = 0;
215 for (t = terminal_list; t; t = t->next)
216 terminal_getsize ((TTY *) t);
222 terminal_read (TTY * _t, void *buf, int len)
224 TERMINAL *t = (TERMINAL *) _t;
227 terminal_dispatch ();
228 set_nonblocking (t->rfd);
232 red = wrap_read (t->rfd, buf, len);
250 terminal_write (TTY * _t, void *buf, int len)
253 TERMINAL *t = (TERMINAL *) _t;
255 terminal_dispatch ();
257 set_blocking (t->wfd);
261 writ = wrap_write (t->wfd, buf, len);
280 terminal_register_handlers (void)
282 struct sigaction sa = { 0 };
284 sa.sa_handler = sigwinch;
285 sa.sa_flags = SA_RESTART;
286 sigaction (SIGWINCH, &sa, NULL);
288 sa.sa_handler = sigint;
289 sa.sa_flags = SA_RESTART;
290 sigaction (SIGINT, &sa, NULL);
295 terminal_open (int rfd, int wfd)
299 struct termios termios;
301 t = (TERMINAL *) xmalloc (sizeof (TERMINAL));
303 strcpy (t->name, "terminal");
307 tcgetattr (wfd, &t->orig_termios);
309 t->next = terminal_list;
312 tcgetattr (wfd, &termios);
314 set_nonblocking (rfd);
315 set_nonblocking (wfd);
318 cfmakeraw (&termios);
319 // raw_termios (&termios);
321 tcsetattr (wfd, TCSANOW, &termios);
323 t->recv = terminal_read;
324 t->xmit = terminal_write;
325 t->close = terminal_close;
329 terminal_getsize ((TTY *) t);