chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / tty.c
index fb60246c51a488e226500193f88cd57ca49c18b7..1ac8c87467fc03e3b1c78f361f48413d6397a361 100644 (file)
--- a/src/tty.c
+++ b/src/tty.c
@@ -10,6 +10,21 @@ static char rcsid[] = "$Id$";
 
 /*
  * $Log$
+ * Revision 1.12  2008/02/22 23:39:27  james
+ * *** empty log message ***
+ *
+ * Revision 1.11  2008/02/20 18:31:53  james
+ * *** empty log message ***
+ *
+ * Revision 1.10  2008/02/15 23:52:12  james
+ * *** empty log message ***
+ *
+ * Revision 1.9  2008/02/15 03:32:07  james
+ * *** empty log message ***
+ *
+ * Revision 1.8  2008/02/14 10:36:18  james
+ * *** empty log message ***
+ *
  * Revision 1.7  2008/02/14 10:34:30  james
  * *** empty log message ***
  *
@@ -204,6 +219,23 @@ baud_to_speed_t (int baud)
 void
 tty_pre_select (TTY * t, fd_set * rfds, fd_set * wfds)
 {
+  int line;
+  struct timeval now, dif;
+
+  if (t->hanging_up)
+    {
+
+      gettimeofday (&now, NULL);
+      timersub (&now, &t->hangup_clock, &dif);
+      if (dif.tv_sec)
+        {
+          line = TIOCM_DTR;
+          ioctl (t->rfd, TIOCMBIS, &line);
+          t->hanging_up = 0;
+        }
+    }
+
+
   FD_SET (t->rfd, rfds);
 }
 
@@ -211,28 +243,163 @@ int
 tty_get_status (TTY * t, TTY_Status * s)
 {
 
-       s->lines=0;
+  s->lines = 0;
   ioctl (t->rfd, TIOCMGET, &s->lines);
 
   if (tcgetattr (t->rfd, &s->termios))
     return -1;
-  s->baud=speed_t_to_baud(cfgetispeed(&s->termios));
+
+  s->baud = speed_t_to_baud (cfgetispeed (&s->termios));
+  s->blocked = t->blocked;
 
   return 0;
 }
 
+void
+tty_set_baud (TTY * t, int rate)
+{
+  struct termios tios = { 0 };
+
+  speed_t s = baud_to_speed_t (rate);
+
+  if (s == (speed_t) - 1)
+    return;
+
+  if (tcgetattr (t->rfd, &tios))
+    return;
+
+  cfsetispeed (&tios, s);
+  cfsetospeed (&tios, s);
+
+  tcsetattr (t->rfd, TCSANOW, &tios);
+}
+
+void
+tty_send_break (TTY * t)
+{
+  tcsendbreak (t->wfd, 0);
+}
+
+void
+tty_set_flow (TTY * t, int flow)
+{
+  struct termios tios = { 0 };
+
+  if (tcgetattr (t->rfd, &tios))
+    return;
+
+  if (flow)
+    tios.c_cflag |= CRTSCTS;
+  else
+    tios.c_cflag &= ~CRTSCTS;
+
+  tcsetattr (t->rfd, TCSANOW, &tios);
+
+}
+
+void
+tty_hangup (TTY * t)
+{
+  int line;
+
+  line = TIOCM_DTR;
+  ioctl (t->rfd, TIOCMBIC, &line);
+
+  t->hanging_up = 1;
+  gettimeofday (&t->hangup_clock, NULL);
+
+}
+
+
 #if 0
-int
-tty_post_select (Context * c, fd_set * rfds, fd_set * wfds)
+typedef struct
 {
+  int in_dle;
+  int in_errmark;
+
+  int bit_edge_frequency[8];
+  int errs;
+}
+#endif
 
-  if (FD_ISSET (c->t->rfd, rfds))
+#define DLE 0377
+
+#define bit(p,b,z,o) \
+       do { \
+         if ((b && z)) { \
+           p->bitfreq[z]++; \
+           z = 0; \
+         } \
+         \
+         if ((!b && o)) \
+         { \
+           p->bitfreq[z]++; \
+           o = 0; \
+         } \
+         \
+         if (b) \
+           o++; \
+         else \
+           z++; \
+         } \
+       while (0)
+
+void
+tty_stats (TTY_Parser * p, int err, int ch)
+{
+  int c = 128;
+  int zc = 0, oc = 0;
+
+  if (err)
+    p->biterrs++;
+
+  bit (p, 0, zc, oc);
+
+  while (c)
     {
-      if (vt102_dispatch (&c))
-        return -1;
+      bit (p,ch & c,zc,oc);
+      c >>= 1;
     }
-  return 0;
+  bit (p, 1, zc, oc);
 }
 
-#endif
+void
+tty_parse (Context * c, uint8_t * buf, int len)
+{
+  TTY_Parser *p = &c->t->parser;
+
+  while (len--)
+    {
+
+      if (p->in_dle)
+        {
+          p->in_dle = 0;
+          switch (*buf)
+            {
+            case DLE:
+              tty_bit_analyse (p, 0, *buf);
+              utf8_parse (c, *buf);
+              break;
+            case 0:
+              p->in_errmark = 1;
+              break;
+            default:
+              log_f (c->l, "%s:%d DLE parsing error: \\377 \\%03o", *buf);
+            }
+        }
+      else if (p->in_errmark)
+        {
+          p->in_errmark = 0;
+          log_f (c->l, "%s:%d tty reports error: \\377 \\000 \\%03o", *buf);
+          utf8_parse (c, *buf);
+          tty_bit_analyse (p, 1, *buf);
+          utf8_parse (c, SYM_CHAR_RESET);
+        }
+      else
+        {
+          tty_bit_analyse (p, 0, *buf);
+          utf8_parse (c, *buf);
+        }
+      buf++;
+    }
+}