chiark / gitweb /
Merge branch 'cvsimport'
[sympathy.git] / src / terminal.c
index a4cd31b4fde6209a2182ee48cf36129ed255409e..22415f4a6257a3990e78960c979d7fd1f691ad95 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/* 
  * terminal.c:
  *
  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
@@ -6,10 +6,80 @@
  *
  */
 
-static char rcsid[] = "$Id$";
+static char rcsid[] =
+  "$Id: terminal.c,v 1.24 2008/03/12 10:47:26 james Exp $";
 
-/*
- * $Log$
+/* 
+ * $Log: terminal.c,v $
+ * Revision 1.24  2008/03/12 10:47:26  james
+ * @@
+ *
+ * Revision 1.23  2008/03/12 01:30:23  james
+ * *** empty log message ***
+ *
+ * Revision 1.22  2008/03/11 17:56:50  james
+ * *** empty log message ***
+ *
+ * Revision 1.21  2008/03/11 17:56:04  james
+ * *** empty log message ***
+ *
+ * Revision 1.20  2008/03/10 11:49:33  james
+ * *** empty log message ***
+ *
+ * Revision 1.19  2008/03/07 14:16:44  james
+ * *** empty log message ***
+ *
+ * Revision 1.18  2008/03/07 14:13:40  james
+ * *** empty log message ***
+ *
+ * Revision 1.17  2008/03/07 13:16:02  james
+ * *** empty log message ***
+ *
+ * Revision 1.16  2008/03/07 12:42:08  james
+ * *** empty log message ***
+ *
+ * Revision 1.15  2008/03/07 12:37:04  james
+ * *** empty log message ***
+ *
+ * Revision 1.14  2008/03/03 06:04:42  james
+ * *** empty log message ***
+ *
+ * Revision 1.13  2008/03/02 10:37:56  james
+ * *** empty log message ***
+ *
+ * Revision 1.12  2008/02/28 16:57:52  james
+ * *** empty log message ***
+ *
+ * Revision 1.11  2008/02/26 23:56:12  james
+ * *** empty log message ***
+ *
+ * Revision 1.10  2008/02/26 23:23:17  james
+ * *** empty log message ***
+ *
+ * Revision 1.9  2008/02/15 03:32:07  james
+ * *** empty log message ***
+ *
+ * Revision 1.8  2008/02/14 10:39:14  james
+ * *** empty log message ***
+ *
+ * Revision 1.7  2008/02/14 01:55:57  james
+ * *** empty log message ***
+ *
+ * Revision 1.6  2008/02/14 00:57:58  james
+ * *** empty log message ***
+ *
+ * Revision 1.5  2008/02/13 18:05:06  james
+ * *** empty log message ***
+ *
+ * Revision 1.4  2008/02/13 16:57:29  james
+ * *** empty log message ***
+ *
+ * Revision 1.3  2008/02/13 09:12:21  james
+ * *** empty log message ***
+ *
+ * Revision 1.2  2008/02/13 01:08:18  james
+ * *** empty log message ***
+ *
  * Revision 1.1  2008/02/12 22:36:46  james
  * *** empty log message ***
  *
@@ -36,41 +106,117 @@ static char rcsid[] = "$Id$";
 #include "project.h"
 
 
-typedef struct TERMINAL_struct
-{
+typedef struct TERMINAL_struct {
   TTY_SIGNATURE;
   struct termios orig_termios;
   struct TERMINAL_struct *next;
 } TERMINAL;
 
 
-static TERMINAL terminal_list=NULL;
+static TERMINAL *terminal_list = NULL;
+int terminal_winches;
+
 
 
 static void
 terminal_close (TTY * _t)
 {
+  char buf[32];
+  int i;
+
   TERMINAL *t = (TERMINAL *) _t;
-  TERMINAL **ptr=&terminal_list;
+  TERMINAL **ptr = &terminal_list;
 
   if (!t)
     return;
 
   /* Take out of cleanup list */
-  while (*ptr && (*ptr != t)) ptr=&((*ptr)->next);
+  while (*ptr && (*ptr != t))
+    ptr = &((*ptr)->next);
+
+  if (*ptr)
+    *ptr = t->next;
 
-  if (*ptr) 
-       *ptr=t->next;
+  tcsetattr (t->wfd, TCSANOW, &t->orig_termios);
 
-  tcsetattr(t->wfd,TCSANOW,&t->orig_termios);
+  set_nonblocking (t->wfd);
 
-  set_blocking(t->rfd);
-  set_blocking(t->wfd);
+
+  t->xmit (_t, "\033%@", 3);    // Leave UTF-8
+  t->xmit (_t, "\033(B", 3);    // US-ASCII in G0
+  t->xmit (_t, "\033)B", 3);    // US-ASCII in G1
+  t->xmit (_t, "\017", 1);      // Select G0
+  t->xmit (_t, "\033[?25h", 6); // Show cursor
+  t->xmit (_t, "\033[r", 3);    // No margins
+  t->xmit (_t, "\033[0m", 4);   // Default attributes
+  i = sprintf (buf, "\033[%d;%dH", t->displayed_length ? (t->displayed_length + 1) : (CRT_ROWS + 1), 1); 
+               // Cursor to bottom
+  t->xmit (_t, buf, i);
+  t->xmit (_t, "\033[J", 3);    // erase rest of screen
+
+  set_blocking (t->rfd);
+  set_blocking (t->wfd);
 
   free (t);
 }
 
 
+void
+terminal_atexit (void)
+{
+  while (terminal_list)
+    terminal_close ((TTY *) terminal_list);
+}
+
+static void
+sigint (int dummy)
+{
+  terminal_atexit ();
+  exit (-1);
+}
+
+static void
+sigwinch (int not)
+{
+  terminal_winches++;
+}
+
+
+void
+terminal_getsize (TTY * _t)
+{
+  TERMINAL *t = (TERMINAL *) _t;
+  struct winsize sz = { 0 };
+
+  if (!t)
+    return;
+
+  if (ioctl (t->wfd, TIOCGWINSZ, &sz)) {
+    t->size.x = CRT_COLS;
+    t->size.y = CRT_ROWS;
+  } else {
+    t->size.x = sz.ws_col;
+    t->size.y = sz.ws_row;
+  }
+}
+
+
+void
+terminal_dispatch (void)
+{
+  TERMINAL *t;
+
+
+  if (!terminal_winches)
+    return;
+
+  terminal_winches = 0;
+
+  for (t = terminal_list; t; t = t->next)
+    terminal_getsize ((TTY *) t);
+
+}
+
 
 static int
 terminal_read (TTY * _t, void *buf, int len)
@@ -78,19 +224,21 @@ terminal_read (TTY * _t, void *buf, int len)
   TERMINAL *t = (TERMINAL *) _t;
   int red, done = 0;
 
-  do
-    {
+  terminal_dispatch ();
+  set_nonblocking (t->rfd);
 
-      red = wrap_read (t->fd, buf, len);
-      if (red < 0)
-        return -1;
-      if (!red)
-        return done;
+  do {
 
-      buf += red;
-      len -= red;
-      done += red;
-    }
+    red = wrap_read (t->rfd, buf, len);
+    if (red < 0)
+      return -1;
+    if (!red)
+      return done;
+
+    buf += red;
+    len -= red;
+    done += red;
+  }
   while (len);
 
 
@@ -104,86 +252,81 @@ terminal_write (TTY * _t, void *buf, int len)
   int writ, done = 0;
   TERMINAL *t = (TERMINAL *) _t;
 
-  do
-    {
+  terminal_dispatch ();
+
+  set_blocking (t->wfd);
 
-      writ = wrap_write (t->fd, buf, len);
-      if (writ < 0)
-        return -1;
-      if (!writ)
-        sleep (1);
+  do {
 
-      buf += writ;
-      len -= writ;
-      done += writ;
-    }
+    writ = wrap_write (t->wfd, buf, len);
+    if (writ < 0)
+      return -1;
+
+    if (!writ)
+      usleep (1000);
+
+    buf += writ;
+    len -= writ;
+    done += writ;
+  }
   while (len);
 
 
   return done;
 }
 
+
+void
+terminal_register_handlers (void)
+{
+  struct sigaction sa = { 0 };
+
+  sa.sa_handler = sigwinch;
+  sa.sa_flags = SA_RESTART;
+  sigaction (SIGWINCH, &sa, NULL);
+
+  sa.sa_handler = sigint;
+  sa.sa_flags = SA_RESTART;
+  sigaction (SIGINT, &sa, NULL);
+}
+
+
 TTY *
-terminal_open (int rfd,int wfd)
+terminal_open (int rfd, int wfd)
 {
   TERMINAL *t;
   pid_t child;
-  char name[1024];
   struct termios termios;
 
-  t = (TERMINAL *) malloc (sizeof (TERMINAL));
+  t = (TERMINAL *) xmalloc (sizeof (TERMINAL));
 
+  strcpy (t->name, "terminal");
   t->rfd = rfd;
   t->wfd = wfd;
 
-  tcgetattr(wfd,&t->orig_termios);
+  tcgetattr (wfd, &t->orig_termios);
 
-  t->next=terminal_list;
-  terminal_list=t;
+  t->next = terminal_list;
+  terminal_list = t;
 
-  tcgetattr(tfd,&termios);
+  tcgetattr (wfd, &termios);
 
   set_nonblocking (rfd);
   set_nonblocking (wfd);
 
 
-  raw_termios (&termios);
+  cfmakeraw (&termios);
+  // raw_termios (&termios);
 
-  tcsetattr(wfd,TCSANOW,&termios);
+  tcsetattr (wfd, TCSANOW, &termios);
 
-  t->read = terminal_read;
-  t->write = terminal_write;
+  t->recv = terminal_read;
+  t->xmit = terminal_write;
   t->close = terminal_close;
+  t->blocked = 0;
 
 
-  return (TTY *) t;
-}
+  terminal_getsize ((TTY *) t);
 
-void
-terminal_getsize (TTY *_t,CRT_POS *pos)
-{
-TERMINAL *t=(TTY *) _t;
-  struct winsize sz = { 0 };
-
-if ((!t) || (!pos)) return;
-
-if (ioctl (a->wfd, TIOCGWINSZ, &sz))
-    {
-      pos->x = CRT_COLS;
-      pos->y = CRT_ROWS;
-    }
-  else
-    {
-      pos->x = sz.ws_col;
-      pos->y = sz.ws_row;
-    }
-}
-
-
-void terminal_atexit(void)
-{
-while (terminal_list)
-       terminal_close(terminal_list);
+  return (TTY *) t;
 }
-
-