diff options
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/ansi.c | 194 | ||||
-rw-r--r-- | src/ansi.h | 15 | ||||
-rw-r--r-- | src/keys.h | 87 | ||||
-rw-r--r-- | src/libsympathy.c | 16 | ||||
-rw-r--r-- | src/project.h | 5 | ||||
-rw-r--r-- | src/prototypes.h | 5 | ||||
-rw-r--r-- | src/vt102.c | 173 |
8 files changed, 388 insertions, 112 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 1c63eaf..a163fd0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,6 +8,9 @@ # $Id$ # # $Log$ +# Revision 1.3 2008/02/07 00:39:13 james +# *** empty log message *** +# # Revision 1.2 2008/02/04 01:32:39 james # *** empty log message *** # @@ -20,7 +23,7 @@ INCLUDES = -SRCS= ansi.c crt.c html.c libsympathy.c render.c testtty.c version.c vt102.c +SRCS= ansi.c crt.c html.c libsympathy.c render.c testtty.c version.c vt102.c tty.c CPROTO=cproto SYMPATHYSRCS=${SRCS} @@ -10,6 +10,9 @@ static char rcsid[] = "$Id$"; /* * $Log$ + * Revision 1.8 2008/02/07 00:39:13 james + * *** empty log message *** + * * Revision 1.7 2008/02/06 20:26:57 james * *** empty log message *** * @@ -34,9 +37,45 @@ static char rcsid[] = "$Id$"; */ #include "project.h" +static void +set_nonblocking (int fd) +{ + long arg; + arg = fcntl (fd, F_GETFL, arg); + arg |= O_NONBLOCK; + fcntl (fd, F_SETFL, arg); +} + +static void +set_blocking (int fd) +{ + long arg; + arg = fcntl (fd, F_GETFL, arg); + arg &= ~O_NONBLOCK; + fcntl (fd, F_SETFL, arg); +} + + +int ansi_read(ANSI *a,void *buf,int n) +{ +int red; + + set_nonblocking(a->fd); +red=read(a->fd,buf,n); + +if (!red) return -1; + +if ((red==-1) && (errno==EAGAIN)) { + return 0; +} + +return red; +} + void ansi_write (ANSI * a, char *buf, int n) { + set_blocking(a->fd); write (a->fd, buf, n); } @@ -338,12 +377,154 @@ ansi_reset (ANSI * a) crt_reset (&a->crt); ansi_cls (a); + ansi_write(a,"\033=",2); ansi_draw (a, &a->crt); } +void ansi_flush_escape(ANSI *a,VT102 *v) +{ +ANSI_Parser *p=&a->parser; +int i; + +for (i=0;i<p->escape_ptr;++i) { +vt102_send(v,p->escape_buf[i]); +} + +p->escape_ptr=0; +p->in_escape=0; +} + +void ansi_parse_deckey(ANSI *a,VT102 *v) +{ +ANSI_Parser *p=&a->parser; +if ((p->escape_buf[1]!='[') && (p->escape_buf[1]!='O')) { + ansi_flush_escape(a,v); + return; +} + +if ((p->escape_buf[2]>='A') || (p->escape_buf[2]<='Z')){ + vt102_send(v,KEY_UP+(p->escape_buf[2]-'A')); +}else if ((p->escape_buf[2]>='a') || (p->escape_buf[2]<='z')){ + vt102_send(v,KEY_154+(p->escape_buf[2]-'a')); +} else { + ansi_flush_escape(a,v); + return; +} +p->in_escape=0; +p->escape_ptr=0; +} + +void ansi_parse_ansikey(ANSI *a,VT102 *v) +{ +ANSI_Parser *p=&a->parser; + +if ((p->escape_buf[1]!='[') ||(p->escape_buf[3]!='~')) { + ansi_flush_escape(a,v); + return; +} +if ((p->escape_buf[2]>='0') || (p->escape_buf[2]<='9')){ + vt102_send(v,KEY_180+(p->escape_buf[2]-'0')); +} else { + ansi_flush_escape(a,v); + return; +} + +p->in_escape=0; +p->escape_ptr=0; +} + + + +void ansi_parse_escape(ANSI *a,VT102 *v) +{ +ANSI_Parser *p=&a->parser; +switch(p->escape_ptr) { +case 0: +case 1: + return; +case 2: + switch (p->escape_buf[1]) { + case '[': + case 'O': + break; + default: + ansi_flush_escape(a,v); + } + break; +case 3: + switch(p->escape_buf[1]) { + case 'O': + ansi_parse_deckey(a,v); + break; + case '[': + if ((p->escape_buf[2]>='A') && + (p->escape_buf[2]<='Z')) + ansi_parse_deckey(a,v); + break; + default: + ansi_flush_escape(a,v); + } + break; +case 4: + switch(p->escape_buf[1]) { + case '[': + ansi_parse_ansikey(a,v); + break; + default: + ansi_flush_escape(a,v); + } + break; +case 5: + ansi_flush_escape(a,v); +} +} + + +void ansi_check_escape(ANSI *a,VT102 *v) +{ +ANSI_Parser *p=&a->parser; + struct timeval now,diff; + gettimeofday(&now,NULL); + timersub(&now,&p->last_escape,&diff); + +#if 0 +fprintf(stderr,"ie %d tl %d.%06d eb %d\n", + p->in_escape,diff.tv_sec,diff.tv_usec,p->escape_ptr); +#endif + +if (!p->in_escape) return; + + + /*Time up?*/ + if (diff.tv_sec || (diff.tv_usec > ANSI_ESCAPE_TIMEOUT)) + ansi_flush_escape(a,v); + +} + void ansi_parse_char(ANSI *a,int c,VT102 *v) { -vt102_send(v,c); +ANSI_Parser *p=&a->parser; + + +/*See if it's time to flush the escape*/ +ansi_check_escape(a,v); + +if (c==033) { + if (p->in_escape) + ansi_flush_escape(a,v); + + p->in_escape++; + p->escape_ptr=0; + gettimeofday(&p->last_escape,NULL); +} + +if (p->in_escape) { + p->escape_buf[p->escape_ptr++]=c; + ansi_parse_escape(a,v); +} else { + vt102_send(v,c); +} + } void ansi_parse(ANSI *a,char *buf,int len,VT102 *v) @@ -357,12 +538,15 @@ int ansi_dispatch(ANSI *a,VT102 *v) char buf[1024]; int red; -red=read(a.fd,buf,sizeof(buf)); -if (red<0) return -1; -if (!red) return -1; +ansi_check_escape(a,v); + + +red=ansi_read(a,buf,sizeof(buf)); +if (red<=0) return red; + +if (*buf==3) return -1; ansi_parse(a,buf,red,v); return 0; } -int @@ -12,6 +12,9 @@ /* * $Log$ + * Revision 1.3 2008/02/07 00:39:13 james + * *** empty log message *** + * * Revision 1.2 2008/02/06 11:30:37 james * *** empty log message *** * @@ -25,6 +28,16 @@ #define ANSI_INVAL -1 +#define ANSI_ESCAPE_BUF_LEN 10 +#define ANSI_ESCAPE_TIMEOUT 100000 /*in ms*/ + +typedef struct { +int in_escape; +struct timeval last_escape; +char escape_buf[ANSI_ESCAPE_BUF_LEN]; +int escape_ptr; +} ANSI_Parser; + typedef struct { int fd; @@ -33,9 +46,9 @@ typedef struct CRT_Pos pos; CRT_Pos size; int hide_cursor; - int attr; + ANSI_Parser parser; } ANSI; @@ -1,24 +1,67 @@ -#define KEY_UP 128 -#define KEY_DOWN 129 -#define KEY_RIGHT 130 -#define KEY_LEFT 131 +#define KEY_UP 128 /*A*/ +#define KEY_DOWN 129 /*B*/ +#define KEY_RIGHT 130 /*C*/ +#define KEY_LEFT 131 /*D*/ +#define KEY_MIDDLE 132 /*E*/ +#define KEY_END 133 /*F*/ +#define KEY_134 134 /*G*/ +#define KEY_HOME 135 /*H*/ +#define KEY_136 136 /*I*/ +#define KEY_137 137 /*J*/ +#define KEY_138 138 /*K*/ +#define KEY_139 139 /*L*/ +#define KEY_ENTER 140 /*M*/ +#define KEY_141 141 /*N*/ +#define KEY_142 142 /*O*/ +#define KEY_PF1 143 /*P*/ +#define KEY_PF2 144 /*Q*/ +#define KEY_PF3 145 /*R*/ +#define KEY_PF4 146 /*S*/ +#define KEY_147 147 /*T*/ +#define KEY_148 148 /*U*/ +#define KEY_149 149 /*V*/ +#define KEY_150 150 /*W*/ +#define KEY_151 151 /*X*/ +#define KEY_152 152 /*Y*/ +#define KEY_153 153 /*Z*/ -#define KEY_0 140 -#define KEY_1 141 -#define KEY_2 142 -#define KEY_3 143 -#define KEY_4 144 -#define KEY_5 145 -#define KEY_6 146 -#define KEY_7 147 -#define KEY_8 148 -#define KEY_9 149 -#define KEY_MINUS 150 -#define KEY_COMMA 151 -#define KEY_PERIOD 152 -#define KEY_ENTER 153 +#define KEY_154 154 /*a*/ +#define KEY_155 155 /*b*/ +#define KEY_156 156 /*c*/ +#define KEY_157 157 /*d*/ +#define KEY_158 158 /*e*/ +#define KEY_159 159 /*f*/ +#define KEY_160 160 /*g*/ +#define KEY_161 161 /*h*/ +#define KEY_162 162 /*i*/ +#define KEY_STAR 163 /*j*/ +#define KEY_PLUS 164 /*k*/ +#define KEY_COMMA 165 /*l*/ +#define KEY_MINUS 166 /*m*/ +#define KEY_PERIOD 167 /*n*/ +#define KEY_DIVIDE 168 /*o*/ +#define KEY_0 169 /*p*/ +#define KEY_1 170 /*q*/ +#define KEY_2 171 /*r*/ +#define KEY_3 172 /*s*/ +#define KEY_4 173 /*t*/ +#define KEY_5 174 /*u*/ +#define KEY_6 175 /*v*/ +#define KEY_7 176 /*w*/ +#define KEY_8 177 /*x*/ +#define KEY_9 178 /*y*/ +#define KEY_179 179 /*z*/ + +#define KEY_180 180 /*0*/ +#define KEY_181 181 /*1*/ +#define KEY_INSERT 182 /*2*/ +#define KEY_DELETE 183 /*3*/ +#define KEY_184 184 /*4*/ +#define KEY_PGUP 185 /*5*/ +#define KEY_PGDN 186 /*6*/ +#define KEY_187 187 /*7*/ +#define KEY_188 188 /*8*/ +#define KEY_189 189 /*9*/ + +#define KEY_NUM 190 -#define KEY_PF1 160 -#define KEY_PF2 161 -#define KEY_PF3 162 -#define KEY_PF4 163 diff --git a/src/libsympathy.c b/src/libsympathy.c index 5c24ef2..8f28c17 100644 --- a/src/libsympathy.c +++ b/src/libsympathy.c @@ -11,6 +11,9 @@ static char rcsid[] = /* * $Log$ + * Revision 1.7 2008/02/07 00:39:13 james + * *** empty log message *** + * * Revision 1.6 2008/02/06 20:26:58 james * *** empty log message *** * @@ -59,7 +62,7 @@ testy (void) fd_set rfd; int fd; char c; - TTY *y; + TTY *t; VT102 *v; @@ -92,13 +95,15 @@ testy (void) FD_SET (t->fd, &rfd); FD_SET (a.fd, &rfd); - if (select (t->fd + 1, &rfd, NULL, NULL, &tv) < 0) - continue; + select (t->fd + 1, &rfd, NULL, NULL, &tv); +#if 0 if (FD_ISSET (a.fd, &rfd)) { - if (ansi_dispatch(&a,v)) break; } +#endif + if (ansi_dispatch(&a,v)) + break; if (FD_ISSET (t->fd, &rfd)) { if (vt102_dispatch (v)) break; @@ -109,8 +114,9 @@ testy (void) had_winch = 0; ansi_getsize (&a); ansi_reset (&a); - ansi_draw (&a, &v.crt); + ansi_draw (&a, &v->crt); } + ansi_draw (&a, &v->crt); } tcsetattr (0, TCSANOW, &old); printf ("QUAT\n"); diff --git a/src/project.h b/src/project.h index 259bb6a..e7ed065 100644 --- a/src/project.h +++ b/src/project.h @@ -12,6 +12,9 @@ /* * $Log$ + * Revision 1.5 2008/02/07 00:39:13 james + * *** empty log message *** + * * Revision 1.4 2008/02/06 20:26:58 james * *** empty log message *** * @@ -72,6 +75,8 @@ #include <termio.h> #include <termios.h> #include <signal.h> +#include <fcntl.h> +#include <errno.h> #include <utmp.h> #include <pty.h> diff --git a/src/prototypes.h b/src/prototypes.h index 9a674db..5bbd01a 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -63,3 +63,8 @@ void vt102_reset(VT102 *v); int vt102_dispatch(VT102 *v); VT102 *vt102_new(TTY *t); void vt102_free(VT102 *v); +/* tty.c */ +TTY *tty_new_test(void); +int tty_read(TTY *t, void *buf, int len); +int tty_write(TTY *t, void *buf, int len); +void tty_free(TTY *t); diff --git a/src/vt102.c b/src/vt102.c index 000ef7b..713ff42 100644 --- a/src/vt102.c +++ b/src/vt102.c @@ -10,6 +10,9 @@ static char rcsid[] = "$Id$"; /* * $Log$ + * Revision 1.12 2008/02/07 00:39:13 james + * *** empty log message *** + * * Revision 1.11 2008/02/06 20:26:58 james * *** empty log message *** * @@ -463,6 +466,12 @@ vt102_change_mode (VT102 * v, int private, char *ns, int set) v->private_modes[m] = set; switch (m) { + case VT102_PRIVATE_MODE_CURSOR_MODE: + if (v->application_keypad_mode) + v->private_modes[m] = 0; + fprintf (stderr, "APPLICATION CURSOR MODE %d\n", + v->private_modes[m]); + break; case VT102_PRIVATE_MODE_ORIGIN_MODE: vt102_cursor_home (v); break; @@ -674,10 +683,10 @@ vt102_parse_esc (VT102 * v, int c) vt102_restore_state (v); break; case '=': - v->application_keypad_mode=1; + v->application_keypad_mode = 1; break; case '>': - v->application_keypad_mode=0; + v->application_keypad_mode = 0; break; default: #if 0 @@ -905,6 +914,7 @@ vt102_parse_char (VT102 * v, int c) { VT102_parser *p = &v->parser; + #if 0 fprintf (stderr, "char %c pc %d %d %d %d %d\n", (c < 32) ? 32 : c, c, p->in_csi, p->in_escape, v->pos.x, v->pos.y); @@ -1013,10 +1023,10 @@ vt102_parse_char (VT102 * v, int c) vt102_status_line (v, "VT102 foo bar baz I'm the urban spaceman baby"); } -vt102_parse(VT102 *v,char *buf,int len) +vt102_parse (VT102 * v, char *buf, int len) { -while (len--) - vt102_parse_char(v,*(buf++)); + while (len--) + vt102_parse_char (v, *(buf++)); } @@ -1033,9 +1043,10 @@ void vt102_send (VT102 * v, uint8_t key) { uint8_t c; - if ((key > 31) || (key < 127)) + fprintf(stderr,"vts: %d(%c)\n",key,(key>31)?key:' '); + if ((key > 31) && (key < 127)) { - tty_write (v->t, &key, 1); + tty_write (v->tty, &key, 1); return; } @@ -1054,14 +1065,14 @@ vt102_send (VT102 * v, uint8_t key) /*LF*/ case 10: /*VT*/ case 11: /*FF*/ case 12: - tty_write (v->t, &key, 1); + tty_write (v->tty, &key, 1); break; /*CR*/ case 13: - tty_write (v->t, &key, 1); + tty_write (v->tty, &key, 1); if (v->modes[VT102_MODE_NEWLINE_MODE]) { c = 10; - tty_write (v->t, &c, 1); + tty_write (v->tty, &c, 1); } break; /*SO*/ case 14: @@ -1077,7 +1088,7 @@ vt102_send (VT102 * v, uint8_t key) /*CAN*/ case 24: /*EM*/ case 25: /*SUB*/ case 26: - tty_write (v->t, &key, 1); + tty_write (v->tty, &key, 1); break; /*ESC*/ case 27: /*FS*/ case 28: @@ -1085,24 +1096,33 @@ vt102_send (VT102 * v, uint8_t key) /*RS*/ case 30: /*US*/ case 31: /*DEL*/ case 127: - tty_write (v->t, &key, 1); + tty_write (v->tty, &key, 1); break; case KEY_UP: case KEY_DOWN: case KEY_RIGHT: case KEY_LEFT: + case KEY_HOME: + case KEY_MIDDLE: + case KEY_END: + if (v->private_modes[VT102_PRIVATE_MODE_CURSOR_MODE]) { - uint8_t buf[] = { 033, '[', 'A' + (key - KEY_UP) }; - tty_write (v->t, &key, sizeof (buf)); + uint8_t buf[] = { 033, 'O', 'A' + (key - KEY_UP) }; + tty_write (v->tty, &buf, sizeof (buf)); } else { - uint8_t buf[] = { 033, '[', 'O' + (key - KEY_UP) }; - tty_write (v->t, &key, sizeof (buf)); + uint8_t buf[] = { 033, '[', 'A' + (key - KEY_UP) }; + tty_write (v->tty, &buf, sizeof (buf)); } break; + case KEY_STAR: + case KEY_PLUS: + case KEY_COMMA: + case KEY_PERIOD: + case KEY_DIVIDE: case KEY_0: case KEY_1: case KEY_2: @@ -1115,65 +1135,47 @@ vt102_send (VT102 * v, uint8_t key) case KEY_9: if (v->application_keypad_mode) { - uint8_t buf[] = { 033, 'O', 'p' + (key - KEY_0) }; - tty_write (v->t, &key, sizeof (buf)); - } - else - { - c = '0' + (key - KEY_0); - tty_write (v->t, &c, 1); - } - break; - case KEY_MINUS: - if (v->application_keypad_mode) - { - uint8_t buf[] = { 033, 'O', 'm' }; - tty_write (v->t, &key, sizeof (buf)); - } - else - { - c = '-'; - tty_write (v->t, &c, 1); - } - break; - case KEY_COMMA: - if (v->application_keypad_mode) - { - uint8_t buf[] = { 033, 'O', 'l' }; - tty_write (v->t, &key, sizeof (buf)); + uint8_t buf[] = { 033, 'O', 'a' + (key - KEY_154) }; + tty_write (v->tty, &buf, sizeof (buf)); } else { - c = ','; - tty_write (v->t, &c, 1); - } - break; - case KEY_PERIOD: - if (v->application_keypad_mode) - { - uint8_t buf[] = { 033, 'O', 'n' }; - tty_write (v->t, &key, sizeof (buf)); - } - else - { - c = '.'; - tty_write (v->t, &c, 1); + static char kpoff[KEY_NUM] = { + [KEY_STAR] = '*', + [KEY_PLUS] = '+', + [KEY_COMMA] = ',', + [KEY_MINUS] = '-', + [KEY_PERIOD] = '.', + [KEY_DIVIDE] = '/', + [KEY_0] = '0', + [KEY_1] = '1', + [KEY_2] = '2', + [KEY_3] = '3', + [KEY_4] = '4', + [KEY_5] = '5', + [KEY_6] = '6', + [KEY_7] = '7', + [KEY_8] = '8', + [KEY_9] = '9' + }; + + tty_write (v->tty, &kpoff[key], 1); } break; case KEY_ENTER: if (v->application_keypad_mode) { uint8_t buf[] = { 033, 'O', 'M' }; - tty_write (v->t, &key, sizeof (buf)); + tty_write (v->tty, &buf, sizeof (buf)); } else { c = 13; - tty_write (v->t, &c, 1); + tty_write (v->tty, &c, 1); if (v->modes[VT102_MODE_NEWLINE_MODE]) { c = 10; - tty_write (v->t, &c, 1); + tty_write (v->tty, &c, 1); } } break; @@ -1183,10 +1185,18 @@ vt102_send (VT102 * v, uint8_t key) case KEY_PF4: { uint8_t buf[] = { 033, 'O', 'P' + (key - KEY_PF1) }; - tty_write (v->t, &key, sizeof (buf)); + tty_write (v->tty, &buf, sizeof (buf)); + } + break; + case KEY_INSERT: + case KEY_DELETE: + case KEY_PGUP: + case KEY_PGDN: + { + uint8_t buf[] = { 033, '[', '0' + (key - KEY_180), '~' }; + tty_write (v->tty, &buf, sizeof (buf)); } break; - } } @@ -1200,7 +1210,7 @@ vt102_reset (VT102 * v) crt_cls (&v->crt); - v->application_keypad_mode=0; + v->application_keypad_mode = 0; v->current_line = v->pos; v->pending_wrap = 0; @@ -1231,34 +1241,41 @@ vt102_reset (VT102 * v) } -int vt102_dispatch(VT102 *v) +int +vt102_dispatch (VT102 * v) { -char buf[1024]; -int red; + char buf[1024]; + int red; -red=tty_read(v->t,buf,sizeof(buf)); -if (red<0) return -1; -if (!red) return 0; + red = tty_read (v->tty, buf, sizeof (buf)); -vt102_parse(v,buf,red); + if (red < 0) + return -1; + if (!red) + return 0; + + + vt102_parse (v, buf, red); -return 0; + return 0; } -VT102 *vt102_new(TTY *t) +VT102 * +vt102_new (TTY * t) { -VT102 *v; + VT102 *v; -v=(VT102 *) malloc(sizeof(VT102)); + v = (VT102 *) malloc (sizeof (VT102)); -vt102_reset(v); + vt102_reset (v); -v->tty=t; + v->tty = t; -return v; + return v; } -void vt102_free(VT102 *v) +void +vt102_free (VT102 * v) { -free(v); + free (v); } |