chiark / gitweb /
*** empty log message ***
[sympathy.git] / src / terminal.c
index a4cd31b4fde6209a2182ee48cf36129ed255409e..a3be09bc62f1b835a7457d1ade6aeade8933dbab 100644 (file)
@@ -6,10 +6,44 @@
  *
  */
 
-static char rcsid[] = "$Id$";
+static char rcsid[] =
+  "$Id$";
 
 /*
  * $Log$
+ * 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 ***
  *
@@ -44,33 +78,111 @@ typedef struct TERMINAL_struct
 } 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[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,10 +190,13 @@ terminal_read (TTY * _t, void *buf, int len)
   TERMINAL *t = (TERMINAL *) _t;
   int red, done = 0;
 
+  terminal_dispatch ();
+  set_nonblocking (t->rfd);
+
   do
     {
 
-      red = wrap_read (t->fd, buf, len);
+      red = wrap_read (t->rfd, buf, len);
       if (red < 0)
         return -1;
       if (!red)
@@ -104,14 +219,19 @@ terminal_write (TTY * _t, void *buf, int len)
   int writ, done = 0;
   TERMINAL *t = (TERMINAL *) _t;
 
+  terminal_dispatch ();
+
+  set_blocking (t->wfd);
+
   do
     {
 
-      writ = wrap_write (t->fd, buf, len);
+      writ = wrap_write (t->wfd, buf, len);
       if (writ < 0)
         return -1;
+
       if (!writ)
-        sleep (1);
+        usleep (1000);
 
       buf += writ;
       len -= writ;
@@ -123,67 +243,58 @@ terminal_write (TTY * _t, void *buf, int 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));
 
+  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;
-}
-
-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;
-    }
-}
-
+  terminal_getsize ((TTY *) t);
 
-void terminal_atexit(void)
-{
-while (terminal_list)
-       terminal_close(terminal_list);
+  return (TTY *) t;
 }
-
-