From: james Date: Thu, 7 Feb 2008 00:39:13 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=sympathy.git;a=commitdiff_plain;h=455df606ac8985c493fc52bcc6d09e0fd27d1cdc *** empty log message *** --- diff --git a/src/ansi.c b/src/ansi.c index 4e951bb..16d9970 100644 --- a/src/ansi.c +++ b/src/ansi.c @@ -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;iescape_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 diff --git a/src/ansi.h b/src/ansi.h index 2a5977b..1b84ddc 100644 --- a/src/ansi.h +++ b/src/ansi.h @@ -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; diff --git a/src/keys.h b/src/keys.h index 89095e1..93b27f9 100644 --- a/src/keys.h +++ b/src/keys.h @@ -1,67 +1,63 @@ -#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_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_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_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 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/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 40bef8e..25d7187 100644 --- a/src/vt102.c +++ b/src/vt102.c @@ -10,6 +10,9 @@ static char rcsid[] = "$Id$"; /* * $Log$ + * Revision 1.14 2008/02/07 00:40:23 james + * *** empty log message *** + * * Revision 1.13 2008/02/07 00:39:59 james * *** empty log message *** * @@ -472,8 +475,10 @@ vt102_change_mode (VT102 * v, int private, char *ns, int set) case VT102_PRIVATE_MODE_CURSOR_MODE: if (v->application_keypad_mode) v->private_modes[m] = 0; +#if 0 fprintf (stderr, "APPLICATION CURSOR MODE %d\n", v->private_modes[m]); +#endif break; case VT102_PRIVATE_MODE_ORIGIN_MODE: vt102_cursor_home (v);