chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / terminal.c
1 /*
2  * terminal.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id$";
10
11 /*
12  * $Log$
13  * Revision 1.1  2008/02/12 22:36:46  james
14  * *** empty log message ***
15  *
16  * Revision 1.1  2008/02/09 15:47:28  james
17  * *** empty log message ***
18  *
19  * Revision 1.2  2008/02/07 11:11:14  staffcvs
20  * *** empty log message ***
21  *
22  * Revision 1.1  2008/02/07 01:02:52  james
23  * *** empty log message ***
24  *
25  * Revision 1.3  2008/02/06 17:53:28  james
26  * *** empty log message ***
27  *
28  * Revision 1.2  2008/02/04 02:05:06  james
29  * *** empty log message ***
30  *
31  * Revision 1.1  2008/02/04 01:32:39  james
32  * *** empty log message ***
33  *
34  */
35
36 #include "project.h"
37
38
39 typedef struct TERMINAL_struct
40 {
41   TTY_SIGNATURE;
42   struct termios orig_termios;
43   struct TERMINAL_struct *next;
44 } TERMINAL;
45
46
47 static TERMINAL terminal_list=NULL;
48
49
50 static void
51 terminal_close (TTY * _t)
52 {
53   TERMINAL *t = (TERMINAL *) _t;
54   TERMINAL **ptr=&terminal_list;
55
56   if (!t)
57     return;
58
59   /* Take out of cleanup list */
60   while (*ptr && (*ptr != t)) ptr=&((*ptr)->next);
61
62   if (*ptr) 
63         *ptr=t->next;
64
65   tcsetattr(t->wfd,TCSANOW,&t->orig_termios);
66
67   set_blocking(t->rfd);
68   set_blocking(t->wfd);
69
70   free (t);
71 }
72
73
74
75 static int
76 terminal_read (TTY * _t, void *buf, int len)
77 {
78   TERMINAL *t = (TERMINAL *) _t;
79   int red, done = 0;
80
81   do
82     {
83
84       red = wrap_read (t->fd, buf, len);
85       if (red < 0)
86         return -1;
87       if (!red)
88         return done;
89
90       buf += red;
91       len -= red;
92       done += red;
93     }
94   while (len);
95
96
97   return done;
98 }
99
100
101 static int
102 terminal_write (TTY * _t, void *buf, int len)
103 {
104   int writ, done = 0;
105   TERMINAL *t = (TERMINAL *) _t;
106
107   do
108     {
109
110       writ = wrap_write (t->fd, buf, len);
111       if (writ < 0)
112         return -1;
113       if (!writ)
114         sleep (1);
115
116       buf += writ;
117       len -= writ;
118       done += writ;
119     }
120   while (len);
121
122
123   return done;
124 }
125
126 TTY *
127 terminal_open (int rfd,int wfd)
128 {
129   TERMINAL *t;
130   pid_t child;
131   char name[1024];
132   struct termios termios;
133
134   t = (TERMINAL *) malloc (sizeof (TERMINAL));
135
136   t->rfd = rfd;
137   t->wfd = wfd;
138
139   tcgetattr(wfd,&t->orig_termios);
140
141   t->next=terminal_list;
142   terminal_list=t;
143
144   tcgetattr(tfd,&termios);
145
146   set_nonblocking (rfd);
147   set_nonblocking (wfd);
148
149
150   raw_termios (&termios);
151
152   tcsetattr(wfd,TCSANOW,&termios);
153
154   t->read = terminal_read;
155   t->write = terminal_write;
156   t->close = terminal_close;
157
158
159   return (TTY *) t;
160 }
161
162 void
163 terminal_getsize (TTY *_t,CRT_POS *pos)
164 {
165 TERMINAL *t=(TTY *) _t;
166   struct winsize sz = { 0 };
167
168 if ((!t) || (!pos)) return;
169
170 if (ioctl (a->wfd, TIOCGWINSZ, &sz))
171     {
172       pos->x = CRT_COLS;
173       pos->y = CRT_ROWS;
174     }
175   else
176     {
177       pos->x = sz.ws_col;
178       pos->y = sz.ws_row;
179     }
180 }
181
182
183 void terminal_atexit(void)
184 {
185 while (terminal_list)
186         terminal_close(terminal_list);
187 }
188
189