chiark / gitweb /
Initial commit of source as found on woking
[sympathy.git] / src / raw.c
1 /* 
2  * raw.c:
3  *
4  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
5  * All rights reserved.
6  *
7  */
8
9 static char rcsid[] = "$Id: raw.c,v 1.10 2011/02/28 18:10:43 james Exp $";
10
11 /* 
12  * $Log: raw.c,v $
13  * Revision 1.10  2011/02/28 18:10:43  james
14  * *** empty log message ***
15  *
16  * Revision 1.9  2011/02/06 16:51:22  james
17  * *** empty log message ***
18  *
19  * Revision 1.8  2008/03/10 11:49:33  james
20  * *** empty log message ***
21  *
22  * Revision 1.7  2008/03/07 13:16:02  james
23  * *** empty log message ***
24  *
25  * Revision 1.6  2008/03/07 12:37:04  james
26  * *** empty log message ***
27  *
28  * Revision 1.5  2008/03/06 21:34:09  james
29  * *** empty log message ***
30  *
31  * Revision 1.4  2008/03/06 21:33:02  james
32  * *** empty log message ***
33  *
34  * Revision 1.3  2008/03/06 17:21:41  james
35  * *** empty log message ***
36  *
37  * Revision 1.2  2008/03/06 16:49:39  james
38  * *** empty log message ***
39  *
40  * Revision 1.1  2008/03/06 16:49:05  james
41  * *** empty log message ***
42  *
43  *
44  */
45
46 #include "project.h"
47
48 typedef struct {
49   RX_SIGNATURE;
50   int rfd;
51   int wfd;
52 } RX_Raw;
53
54 typedef struct {
55   TTY_SIGNATURE;
56 } RAW_TERMINAL;
57
58
59 static int
60 rx_raw_rx (RX * _r, int ch)
61 {
62   RX_Raw *r = (RX_Raw *) _r;
63   int ret;
64   uint8_t c = ch;
65   set_blocking (r->wfd);
66   ret = (write (r->wfd, &c, 1) == 1) ? 0 : -1;
67 }
68
69 static void
70 rx_raw_close (RX * r)
71 {
72   free (r);
73 }
74
75 RX *
76 rx_new_raw (int rfd, int wfd)
77 {
78   RX_Raw *ret;
79
80   ret = xmalloc (sizeof (RX_Raw));
81   memset (ret, 0, sizeof (RX_Raw));
82
83   ret->rx = rx_raw_rx;
84   ret->close = rx_raw_close;
85
86   ret->rfd = rfd;
87   ret->wfd = wfd;
88
89   return (RX *) ret;
90 }
91
92 static int my_wrap_read (int fd, void *buf, int len)
93 {
94   int red;
95
96   red = read (fd, buf, len);
97 #if 1
98   if (!red)
99     return -1;
100 #endif
101
102   if ((red < 0) && (errno == EAGAIN))
103     red = 0;
104
105   return red;
106 }
107
108
109
110 static int
111 raw_terminal_read (TTY * _t, void *buf, int len)
112 {
113   RAW_TERMINAL *t = (RAW_TERMINAL *) _t;
114   int red, done = 0;
115
116   set_nonblocking (t->rfd);
117
118   do {
119
120     red = my_wrap_read (t->rfd, buf, len);
121     if (red < 0)
122         return done ? done:-1;
123     if (!red)
124       return done;
125
126     buf += red;
127     len -= red;
128     done += red;
129   }
130   while (len);
131
132
133   return done;
134 }
135
136
137 static int
138 raw_terminal_write (TTY * _t, void *buf, int len)
139 {
140   int writ, done = 0;
141   RAW_TERMINAL *t = (RAW_TERMINAL *) _t;
142
143   set_blocking (t->wfd);
144
145   do {
146
147     writ = wrap_write (t->wfd, buf, len);
148     if (writ < 0)
149       return -1;
150
151     if (!writ)
152       usleep (1000);
153
154     buf += writ;
155     len -= writ;
156     done += writ;
157   }
158   while (len);
159
160
161   return done;
162 }
163
164
165
166 static void
167 raw_terminal_close (TTY * _t)
168 {
169   RAW_TERMINAL *t = (RAW_TERMINAL *) _t;
170   set_blocking (t->rfd);
171   set_blocking (t->wfd);
172
173   free (t);
174 }
175
176
177 TTY *
178 terminal_new_raw (int rfd, int wfd)
179 {
180   RAW_TERMINAL *t;
181
182   t = (RAW_TERMINAL *) malloc (sizeof (RAW_TERMINAL));
183   memset (t, 0, sizeof (t));
184
185   strcpy (t->name, "raw");
186   t->rfd = rfd;
187   t->wfd = wfd;
188
189   set_nonblocking (rfd);
190   set_nonblocking (wfd);
191
192   t->recv = raw_terminal_read;
193   // t->xmit = raw_terminal_write;
194   t->close = raw_terminal_close;
195   t->blocked = 0;
196
197   return (TTY *) t;
198 }
199
200 static void
201 ansi_raw_one_shot (ANSI * a, CRT * c)
202 {
203 }
204
205 static int
206 ansi_raw_key (ANSI * a, Context * c, int key)
207 {
208   return c->k->key (c->k, c, key);
209 }
210
211 static void
212 ansi_raw_parse (ANSI * a, Context * c, uint8_t * buf, int red)
213 {
214   while (red--)
215     ansi_raw_key (a, c, *(buf++));
216 }
217
218 static int
219 ansi_raw_dispatch (ANSI * a, Context * c)
220 {
221   char buf[1024];
222   int red;
223
224   if (!a->terminal)
225     return 0;
226
227   red = a->terminal->recv (a->terminal, buf, sizeof (buf));
228   if (red <= 0)
229     return red;
230
231   ansi_raw_parse (a, c, buf, red);
232
233   return 0;
234 }
235 static void
236 ansi_raw_free (ANSI * a)
237 {
238   free (a);
239 }
240
241 ANSI *
242 ansi_new_raw (int rfd, int wfd)
243 {
244   ANSI *ret;
245
246   ret = malloc (sizeof (ANSI));
247   memset (ret, 0, sizeof (ANSI));
248
249   ret->terminal = terminal_new_raw (rfd, wfd);
250   ret->dispatch = ansi_raw_dispatch;
251   ret->close = ansi_raw_free;
252
253   return ret;
254 }