chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / tty.c
index 72b31a12f161cfe615255166559466a585aaeba2..1ac8c87467fc03e3b1c78f361f48413d6397a361 100644 (file)
--- a/src/tty.c
+++ b/src/tty.c
@@ -10,6 +10,27 @@ 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 ***
+ *
+ * Revision 1.6  2008/02/13 16:59:34  james
+ * *** empty log message ***
+ *
  * Revision 1.5  2008/02/13 16:57:29  james
  * *** empty log message ***
  *
@@ -22,25 +43,363 @@ static char rcsid[] = "$Id$";
  */
 
 
+#include "project.h"
 
+static int
+speed_t_to_baud (speed_t s)
+{
+  switch (s)
+    {
+#ifdef B0
+    case B0:
+      return 0;
+#endif
+#ifdef B50
+    case B50:
+      return 50;
+#endif
+#ifdef B75
+    case B75:
+      return 75;
+#endif
+#ifdef B110
+    case B110:
+      return 110;
+#endif
+#ifdef B134
+    case B134:
+      return 134;
+#endif
+#ifdef B150
+    case B150:
+      return 150;
+#endif
+#ifdef B200
+    case B200:
+      return 200;
+#endif
+#ifdef B300
+    case B300:
+      return 300;
+#endif
+#ifdef B600
+    case B600:
+      return 600;
+#endif
+#ifdef B1200
+    case B1200:
+      return 1200;
+#endif
+#ifdef B1800
+    case B1800:
+      return 1800;
+#endif
+#ifdef B2400
+    case B2400:
+      return 2400;
+#endif
+#ifdef B4800
+    case B4800:
+      return 4800;
+#endif
+#ifdef B9600
+    case B9600:
+      return 9600;
+#endif
+#ifdef B19200
+    case B19200:
+      return 19200;
+#endif
+#ifdef B38400
+    case B38400:
+      return 38400;
+#endif
+#ifdef B57600
+    case B57600:
+      return 57600;
+#endif
+#ifdef B115200
+    case B115200:
+      return 115200;
+#endif
+#ifdef B230400
+    case B230400:
+      return 230400;
+#endif
+    }
+
+  return -1;
+}
+
+static speed_t
+baud_to_speed_t (int baud)
+{
+  switch (baud)
+    {
+#ifdef B0
+    case 0:
+      return B0;
+#endif
+#ifdef B50
+    case 50:
+      return B50;
+#endif
+#ifdef B75
+    case 75:
+      return B75;
+#endif
+#ifdef B110
+    case 110:
+      return B110;
+#endif
+#ifdef B134
+    case 134:
+      return B134;
+#endif
+#ifdef B150
+    case 150:
+      return B150;
+#endif
+#ifdef B200
+    case 200:
+      return B200;
+#endif
+#ifdef B300
+    case 300:
+      return B300;
+#endif
+#ifdef B600
+    case 600:
+      return B600;
+#endif
+#ifdef B1200
+    case 1200:
+      return B1200;
+#endif
+#ifdef B1800
+    case 1800:
+      return B1800;
+#endif
+#ifdef B2400
+    case 2400:
+      return B2400;
+#endif
+#ifdef B4800
+    case 4800:
+      return B4800;
+#endif
+#ifdef B9600
+    case 9600:
+      return B9600;
+#endif
+#ifdef B19200
+    case 19200:
+      return B19200;
+#endif
+#ifdef B38400
+    case 38400:
+      return B38400;
+#endif
+#ifdef B57600
+    case 57600:
+      return B57600;
+#endif
+#ifdef B115200
+    case 115200:
+      return B115200;
+#endif
+#ifdef B230400
+    case 230400:
+      return B230400;
+#endif
+    }
+  return -1;
+}
 
 void
 tty_pre_select (TTY * t, fd_set * rfds, fd_set * wfds)
 {
-  FD_SET (t->rfd, &rfds);
+  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);
+}
+
+int
+tty_get_status (TTY * t, TTY_Status * s)
+{
+
+  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->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
+
+#define DLE 0377
 
-  if (FD_ISSET (c->t->rfd, rfds))
+#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++;
+    }
+}