-/*
+/*
* terminal.c:
*
* Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
*
*/
-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 ***
*
#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;
+
+ tcsetattr (t->wfd, TCSANOW, &t->orig_termios);
- if (*ptr)
- *ptr=t->next;
+ set_nonblocking (t->wfd);
- tcsetattr(t->wfd,TCSANOW,&t->orig_termios);
- 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)
+void
+terminal_atexit (void)
{
-while (terminal_list)
- terminal_close(terminal_list);
+ while (terminal_list)
+ terminal_close ((TTY *) terminal_list);
}
-static void sigint(int dummy)
+static void
+sigint (int dummy)
{
-terminal_atexit();
-exit(-1);
+ terminal_atexit ();
+ exit (-1);
}
static void
void
-terminal_getsize (TTY *_t)
+terminal_getsize (TTY * _t)
{
-TERMINAL *t=(TTY *) _t;
+ TERMINAL *t = (TERMINAL *) _t;
struct winsize sz = { 0 };
-if (!t) return;
-
-if (ioctl (a->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;
- }
+ 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)
+void
+terminal_dispatch (void)
{
-TERMINAL *t;
+ TERMINAL *t;
-if (!terminal_winches) return;
+ if (!terminal_winches)
+ return;
-terminal_winches=0;
+ terminal_winches = 0;
-for (t=terminal_list;t;t=t->next)
-terminal_getsize(t);
+ for (t = terminal_list; t; t = t->next)
+ terminal_getsize ((TTY *) t);
}
TERMINAL *t = (TERMINAL *) _t;
int red, done = 0;
- terminal_dispatch();
+ terminal_dispatch ();
+ set_nonblocking (t->rfd);
- do
- {
+ do {
- red = wrap_read (t->fd, buf, len);
- if (red < 0)
- return -1;
- if (!red)
- return done;
+ red = wrap_read (t->rfd, buf, len);
+ if (red < 0)
+ return -1;
+ if (!red)
+ return done;
- buf += red;
- len -= red;
- done += red;
- }
+ buf += red;
+ len -= red;
+ done += red;
+ }
while (len);
int writ, done = 0;
TERMINAL *t = (TERMINAL *) _t;
- terminal_dispatch();
+ terminal_dispatch ();
+
+ set_blocking (t->wfd);
+
+ do {
- do
- {
+ writ = wrap_write (t->wfd, buf, len);
+ if (writ < 0)
+ return -1;
- writ = wrap_write (t->fd, buf, len);
- if (writ < 0)
- return -1;
- if (!writ)
- sleep (1);
+ if (!writ)
+ usleep (1000);
- buf += writ;
- len -= writ;
- done += writ;
- }
+ buf += writ;
+ len -= writ;
+ done += writ;
+ }
while (len);
}
-void terminal_register_handlers(void)
+void
+terminal_register_handlers (void)
{
- struct sigaction sa = { 0 };
+ struct sigaction sa = { 0 };
- sa.sa_handler = sigwinch;
- sa.sa_flags = SA_RESTART;
- sigaction (SIGWINCH, &sa, NULL);
+ 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);
+ 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;
- terminal_getsize((TTY*) t);
+ terminal_getsize ((TTY *) t);
return (TTY *) t;
}
-