194 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			194 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *		emulateur de terminal
 | |
|  */
 | |
|  
 | |
| #include  <stdio.h>
 | |
| #include  <string.h>
 | |
| #include <unistd.h>
 | |
| #include <stdlib.h>
 | |
| #include  <errno.h>
 | |
| #include  <time.h>
 | |
| #include <sys/time.h>
 | |
| #include <sys/select.h>
 | |
| 
 | |
| #include <ncurses.h>
 | |
| 
 | |
| #include  "../serial/serial.h"
 | |
| #include  "terminal.h"
 | |
| 
 | |
| extern int	verbosity;
 | |
| 
 | |
| int special_dumper(FILE *fp, unsigned char octet);
 | |
| 
 | |
| /* ---------------------------------------------------------------- */
 | |
| static void bordure(WINDOW * w, char *texte, int type)
 | |
| {
 | |
| if (type)
 | |
| 	box(w, 0, 0);
 | |
| else
 | |
| 	wborder(w, '|', '|', '-', '-', '+', '+', '+', '+');
 | |
| wstandout(w); mvwaddstr(w, 0, 3, texte); wstandend(w);
 | |
| wrefresh(w);
 | |
| }
 | |
| /* ---------------------------------------------------------------- */
 | |
| static int interactive(WINDOW *glass, int fd_local, int fd_remote)
 | |
| {
 | |
| int		flag_exit = 0;
 | |
| long		tstart, tcur;
 | |
| char		ligne[100];
 | |
| int		received;
 | |
| 
 | |
| /* --- variables for select */
 | |
| struct timeval	tv;
 | |
| fd_set		rfds;
 | |
| int		retval,mfd;
 | |
| 
 | |
| #if DEBUG_LEVEL
 | |
| fprintf(stderr, ">>> %s ( %p %d %d )\n", __func__,
 | |
| 				glass, fd_local, fd_remote);
 | |
| #endif
 | |
| 
 | |
| tstart = time(NULL);	
 | |
| 
 | |
| wclear(glass);		wrefresh(glass);
 | |
| 
 | |
| mfd = (fd_local>fd_remote ? fd_local : fd_remote) + 1;		/* XXX */
 | |
| 
 | |
| #if DEBUG_LEVEL
 | |
| sprintf(ligne, "%s : mfd is %d\n", __func__, mfd);
 | |
| waddstr(glass, ligne); wrefresh(glass);
 | |
| #endif
 | |
| 
 | |
| do	{
 | |
| 	tcur = time(NULL);
 | |
| 
 | |
| 	FD_ZERO(&rfds);
 | |
| 	FD_SET(fd_local, &rfds);	/* stdin */
 | |
| 	FD_SET(fd_remote, &rfds);	/* teletype */
 | |
| 	tv.tv_sec = tv.tv_usec = 0;	/* no timeout */
 | |
| 
 | |
| 	retval = select(mfd, &rfds, NULL, NULL, &tv);	
 | |
| 	if (-1 == retval) {
 | |
| 		sprintf(ligne, "err select %s\n", strerror(errno));
 | |
| 		waddstr(glass, ligne); wrefresh(glass);
 | |
| 		continue;
 | |
| 		}
 | |
| 
 | |
| 	/*** est-ce la liaison serie ? */
 | |
| 	if (FD_ISSET(fd_remote, &rfds)) {
 | |
| 		/* get the incoming byte */
 | |
| 		received = getbyte(fd_remote);
 | |
| 		if (verbosity) {
 | |
| 			special_dumper(stderr, received);
 | |
| 			fflush(stderr);
 | |
| 			}
 | |
| 
 | |
| 		if ('\r' != received) waddch(glass, received);
 | |
| 		}
 | |
| 
 | |
| 	/*** est-ce le yuser avec son clavier ? */
 | |
| 	if (FD_ISSET(fd_local, &rfds)) {
 | |
| 		noecho();
 | |
| 		received = wgetch(glass);
 | |
| 		echo();
 | |
| 
 | |
| #if DEBUG_LEVEL > 1
 | |
| 		sprintf(ligne, " got $%X\n", received); 
 | |
| 		waddstr(glass, ligne); wrefresh(glass);
 | |
| #endif
 | |
| 
 | |
| 		if (0==received)	sleep(1);	/* anti ddos */
 | |
| 
 | |
| 		/* que doit-on faire avec ce qu'on
 | |
| 			vient de recevoir ? */
 | |
| 		if (0x04 == received) {		/* EOT (end of transmission) */
 | |
| 			waddstr(glass, "--- EOT ---\n"); wrefresh(glass);
 | |
| 			flag_exit = 1;
 | |
| 			}
 | |
| 
 | |
| 		putbyte(fd_remote, received);		
 | |
| 		}
 | |
| 
 | |
| 	wrefresh(glass);
 | |
| 
 | |
| 	} while (! flag_exit);
 | |
| 
 | |
| sleep(1);
 | |
| 
 | |
| return -1;
 | |
| }
 | |
| /* ---------------------------------------------------------------- */
 | |
| int run_the_terminal(int fd_serial, char *title, WINDOW *win)
 | |
| {
 | |
| WINDOW		*terminal, *ecran;
 | |
| int		wid_term, hei_term, lin_term, col_term;
 | |
| int		foo;
 | |
| // char		ligne[100];
 | |
| // unsigned char	byte;
 | |
| int		fd_stdin;
 | |
| 
 | |
| lin_term = 4;	col_term = 9;			/* position */
 | |
| wid_term = 60;	hei_term = 25;			/* dimensions */
 | |
| 
 | |
| fd_stdin = fileno(stdin);	/* for select or pool */
 | |
| 
 | |
| terminal = newwin(hei_term, wid_term, lin_term, col_term);
 | |
| if ( NULL==terminal )	return -1;
 | |
| bordure(terminal, title, 1);
 | |
| 
 | |
| ecran = subwin(terminal, hei_term-2, wid_term-2, lin_term+1, col_term+1);
 | |
| if ( NULL==ecran )	return -2;
 | |
| scrollok(ecran, 1);
 | |
| 
 | |
| if (verbosity) {
 | |
| 	foo = mvwaddstr(ecran, 2, 14, "SCREEN READY\n");
 | |
| #if DEBUG_LEVEL > 1
 | |
| 	fprintf(stderr, "in '%s', mvwaddstr -> %d\n", __func__, foo);
 | |
| #endif
 | |
| 	wrefresh(ecran);	sleep(1);
 | |
| 	}
 | |
| 
 | |
| foo = interactive(ecran, fd_stdin, fd_serial);
 | |
| if (foo) {
 | |
| 	fprintf(stderr, "interactive -> %d\n", foo);
 | |
| 	sleep(1);
 | |
| 	}
 | |
| 
 | |
| delwin(terminal);
 | |
| touchwin(stdscr);			wrefresh(stdscr);
 | |
| 
 | |
| return 0;
 | |
| }
 | |
| /* ---------------------------------------------------------------- */
 | |
| int essai_terminal(int fd, char *txt, int k)
 | |
| {
 | |
| int		lig, col;
 | |
| int		foo, retv;
 | |
| 
 | |
| #if DEBUG_LEVEL
 | |
| fprintf(stderr, ">>> %s ( %d '%s' %d )\n", __func__,
 | |
| 				fd, txt, k );
 | |
| #endif
 | |
| 
 | |
| /*** initialisation de curses */				
 | |
| initscr();
 | |
| nonl();         cbreak();       noecho();
 | |
| 
 | |
| for (lig=0; lig<LINES; lig++) {
 | |
| 	for (col=0; col<COLS; col++) {
 | |
| 		mvaddch(lig, col, "o+OX"[rand()%4]);	
 | |
| 		}
 | |
| 	}
 | |
| wrefresh(stdscr);
 | |
| 
 | |
| /*** passons a la partie active */
 | |
| retv = run_the_terminal(fd, txt, stdscr);
 | |
| 
 | |
| /*** terminaison de curses */
 | |
| endwin();       
 | |
| fprintf(stderr, "terminal return %d\n", retv);
 | |
| 
 | |
| return 0;
 | |
| }
 | |
| /* ---------------------------------------------------------------- */
 | 
