diff options
Diffstat (limited to 'libterm')
| -rw-r--r-- | libterm/Makefile | 16 | ||||
| -rw-r--r-- | libterm/screen_modes.c | 3 | ||||
| -rw-r--r-- | libterm/term.c | 361 | ||||
| -rw-r--r-- | libterm/term_gui.c | 31 | ||||
| -rw-r--r-- | libterm/term_io.c | 336 | 
5 files changed, 747 insertions, 0 deletions
| diff --git a/libterm/Makefile b/libterm/Makefile new file mode 100644 index 0000000..759b3f5 --- /dev/null +++ b/libterm/Makefile @@ -0,0 +1,16 @@ +PROJECT=libterm +CC=gcc +LD=ld +CFLAGS=-g3 + +make: +	$(CC) $(CFLAGS) -c term.c +	$(CC) $(CFLAGS) -c screen_modes.c +	$(CC) $(CFLAGS) -c term_io.c +	$(CC) $(CFLAGS) -c term_gui.c +	$(LD) -r term.o screen_modes.o term_io.o term_gui.o -o $(PROJECT).o + +clean: +	rm *.o + + diff --git a/libterm/screen_modes.c b/libterm/screen_modes.c new file mode 100644 index 0000000..709b332 --- /dev/null +++ b/libterm/screen_modes.c @@ -0,0 +1,3 @@ +#include "screen_modes.h" + + diff --git a/libterm/term.c b/libterm/term.c new file mode 100644 index 0000000..81d967e --- /dev/null +++ b/libterm/term.c @@ -0,0 +1,361 @@ +#include "term.h" + +#include "debug.h" + +#define T_ESC "\x1b" + +//setup initial terminal stuff +//this coulc act differently, becouse allways there is  +//different terminal setting that should be default +int term_init( term_screen *term ) +{ +	int ret=0; + +	memset( term, 0, sizeof( term_screen )); + +	if ( !isatty(STDIN_FILENO) ) +	{ +		ERROR("isatty failed\n") +		goto exit_error; +	} +	//!!!!!! +	//register atexit + +	term->ifd = STDIN_FILENO; +	term->ofd = STDOUT_FILENO; + +	//if you whant raw mode then you should set it man +	if ( tcgetattr( term->ifd, &term->orig_i ) == -1 ) goto exit_error; +	term->raw_i = term->orig_i; +	if ( tcgetattr( term->ofd, &term->orig_o ) == -1 ) goto exit_error; +	term->raw_o = term->orig_o; + +	term->mode = SCREEN_MODE_80x25;  + +	return ret; + +exit_error: +	errno = ENOTTY; +	return -1; +} + +//set terminal speed return 0 if OK and 1 if not +//im trust to input arguments that they are ok +int term_set_speed( term_screen *ts, speed_t speed) +{ +	int ret = cfsetospeed( &ts->raw_o, speed ); +	ret = tcsetattr( ts->ofd, TCSANOW, &ts->raw_o ); +	if ( ret != 0 ) +		return 1; + +	//if baudrate set to there then input speed same as  +	//output speed +	cfsetispeed( &ts->raw_i, B0); +	ret = tcsetattr( ts->ifd, TCSANOW, &ts->raw_i ); +	if ( ret != 0 ) +		return 1; +	return 0; +} + +//get maximal number of columns setting up cursor to 999 column +//and getting on with place terminal have placed cursor and getting +//column on with terminal putted cursor +int term_get_maxcol( term_screen *ts ) +{ +	int ret=-1; +	int orig_c; +	int cur_c; + +	/* get initial cursor position */ +	if ( (orig_c = term_cur_get_c( ts )) == -1 ) +		goto exit_error; + + +	/* go to right marging and get position */ +	if ( write( ts->ofd, T_ESC "[999C", 6 ) != 6 ) +		goto exit_error; +	if ( (cur_c = term_cur_get_c( ts )) == -1 ) +		goto exit_error; +	ret = cur_c; + +	/* restore position */ +	{ +		char buf[32]; +		snprintf( buf, 32, T_ESC "[" "%d" "D", cur_c-orig_c); +		write( ts->ofd, buf, strlen(buf) ); +	} + +	return ret; + +exit_error: +	return -1; + +} + +//try to setup far away line after that read position where +//terminal have putted cursor and read line of that postion +int term_get_maxrow( term_screen *ts ) +{ +	int ret=-1; +	int orig_r; +	int cur_r; + +	/* get initial cursor position */ +	if ( (orig_r = term_cur_get_r( ts )) == -1 ) +		goto exit_error; + + +	/* go to right marging and get position */ +	if ( write( ts->ofd, T_ESC "[999B", 6 ) != 6 ) +		goto exit_error; +	if ( (cur_r = term_cur_get_r( ts )) == -1 ) +		goto exit_error; +	ret = cur_r; + +	/* restore position */ +	{ +		char buf[32]; +		snprintf( buf, 32, T_ESC "[" "%d" "A", cur_r-orig_r); +		write( ts->ofd, buf, strlen(buf) ); +	} + +	return ret; + +exit_error: +	return -1; +} + + + +int term_cur_get_c( term_screen *ts ) +{ +	unsigned int i; +	int row, col; +	char buf[32]; +	 +	if ( write( ts->ofd, "\x1b[6n", 4 ) != 4 ) goto exit_error; +	 +	i = 0; +	while (i < sizeof(buf)-1) +	{ +		if ( read( ts->ifd, buf+i,1 ) != 1 ) break; +		if (buf[i] == 'R') break; +		i++; +	} +	buf[i] = '\0'; +	 +	/* Parse terminal response */ +	if ( buf[0] != '\x1b' || buf[1] != '[' ) goto exit_error; +	if ( sscanf( buf+2, "%d;%d", &row, &col) != 2 ) goto exit_error; + +	return col; +exit_error: +	return -1; +} + + +int term_cur_get_r( term_screen *ts ) +{ +	unsigned int i; +	int row, col; +	char buf[32]; +	 +	if ( write( ts->ofd, "\x1b[6n", 4 ) != 4 ) goto exit_error; +	 +	i = 0; +	while (i < sizeof(buf)-1) +	{ +		if ( read( ts->ifd, buf+i,1 ) != 1 ) break; +		if (buf[i] == 'R') break; +		i++; +	} +	buf[i] = '\0'; +	 +	/* Parse terminal response */ +	if ( buf[0] != '\x1b' || buf[1] != '[' ) goto exit_error; +	if ( sscanf( buf+2, "%d;%d", &row, &col) != 2 ) goto exit_error; + +	return row; +exit_error: +	return -1; +} + +//set cursor column position +int term_cur_set_c( term_screen *ts, unsigned int pc ) +{ +	int ret = 0; +	int cur_r; + +	/* go to right marging and get position */ +	if ( (cur_r = term_cur_get_r( ts )) == -1 ) +		goto exit_error; +	/* set position */ +	{ +		char buf[32]; +		int l; + +		snprintf( buf, 32, T_ESC "[%d;%dH", cur_r, pc); +		l = strlen( buf ); +		if ( write( ts->ofd, buf, l ) != l) +			goto exit_error; +	} + +	return ret; + +exit_error: +	return -1; +} + +//set cursor row/line position +int term_cur_set_r( term_screen *ts, unsigned int pr ) +{ +	int ret = 0; +	int cur_c; + +	/* go to right marging and get position */ +	if ( (cur_c = term_cur_get_c( ts )) == -1 ) +		goto exit_error; +	/* set position */ +	{ +		char buf[32]; +		int l; + +		snprintf( buf, 32, T_ESC "[%d;%dH", pr, cur_c); +		l = strlen( buf ); +		if ( write( ts->ofd, buf, l ) != l) +			goto exit_error; +	} + +	return ret; + +exit_error: +	return -1; +} + +int term_cur_set_cr( term_screen *ts, unsigned int pc, unsigned int pr ) +{ +	int ret = 0; + +	/* set position */ +	{ +		char buf[32]; +		int l; + +		snprintf( buf, 32, T_ESC "[%d;%dH", pr, pc); +		l = strlen( buf ); +		if ( write( ts->ofd, buf, l ) != l) +			goto exit_error; +	} +	return ret; + +exit_error: +	return -1; + +} + + +//clean terminal with escape command  +int term_clr_scr( term_screen *ts ) +{ +	int ret = 0; + +	if ( write( ts->ofd, T_ESC "[H" T_ESC "[2J", 7 ) <= 0 ){}; + +	return ret; +} + +//set terminal default input/output behavior +int term_set_raw_mode( term_screen *ts ) +{ +	int ret = 0; + +	if ( tcgetattr( ts->ifd, &ts->orig_i ) == -1 ) +	{ +		ERROR("Cannot get input terminal attributes\n"); +		goto exit_error; +	} + +	ts->raw_i = ts->orig_i; /* modify the original mode */ +	/* input modes: no break, no CR to NL, no parity check, no strip char, +	 * no start/stop output control. */ +	ts->raw_i.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); +	/* output modes - disable post raw */ +	ts->raw_i.c_oflag &= ~(OPOST); +	/* control modes - set 8 bit chars */ +	ts->raw_i.c_cflag |= (CS8); +	/* local modes - choing off, canonical off, no extended functions, +	 * no signal chars (^Z,^C) */ +	ts->raw_i.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); +	/* control chars - set return condition: min number of bytes and timer. +	 * We want read to return every single byte, without timeout. */ +	ts->raw_i.c_cc[VMIN] = 1;  +	ts->raw_i.c_cc[VTIME] = 0; /* 1 byte, no timer */ + +	/* put terminal in raw mode after flushing */ +	if (tcsetattr( ts->ifd, TCSAFLUSH, &ts->raw_i) < 0) +	{ +		ERROR("Cannot set new terminal input attribures\n"); +		goto exit_error; +	} + +	return ret; + +exit_error: +	errno = ENOTTY; +	return -1; + +} + + +//if there is no mode with some rows/columns , then just show that no mode setet +// up and user should decide by his own what to do +int term_mode_rows( term_screen *ts ) +{ +	int ret = -1; + +	if ( ts == NULL) return -1; + +	switch ( ts->mode ) +	{ +		//--------------------- +		case SCREEN_MODE_80x25: +			ret = 25; +			break; +		//-------------------- +		case SCREEN_MODE_NONE: +		default: +			ret = -1; +	} + +	return ret; +} + + +//if there is no mode with some rows/columns , then just show that no mode setet +// up and user should decide by his own what to do +int term_mode_columns( term_screen *ts ) +{ +	int ret = -1; + +	if ( ts == NULL) return -1; + +	switch ( ts->mode ) +	{ +		//--------------------- +		case SCREEN_MODE_80x25: +			ret = 80; +			break; +		//-------------------- +		case SCREEN_MODE_NONE: +		default: +			ret = -1; +	} + +	return ret; +} + + +void term_set_orig_mode( term_screen *ts ) +{ +	tcsetattr( ts->ifd, TCSAFLUSH, &ts->orig_i ); +}
\ No newline at end of file diff --git a/libterm/term_gui.c b/libterm/term_gui.c new file mode 100644 index 0000000..dcdc840 --- /dev/null +++ b/libterm/term_gui.c @@ -0,0 +1,31 @@ +#include "term_gui.h" + +int term_gui_init( term_gui *tg, term_screen *ts ) +{ +	return 0; +} + + +int term_set_wh( term_screen *tg, int width, int height ) +{ +	return 0; +} + + +int term_gui_input_box( term_gui *ts, int x, int y, int w, int h, char *prompt,  +		char *str, size_t sz ) +{ +	return 0; +} + + +int term_gui_draw( term_gui *tg ) +{ +	return 0; +} + + +int term_gui_destroy( term_gui *tg ) +{ +	return 0; +}
\ No newline at end of file diff --git a/libterm/term_io.c b/libterm/term_io.c new file mode 100644 index 0000000..a1f157c --- /dev/null +++ b/libterm/term_io.c @@ -0,0 +1,336 @@ +#include "term_io.h" + +int term_fprint( screen_mode_e mode, FILE *f ) +{ +	int ret=-1; +	if (f == NULL) +		return -1; +	 +	ERROR("\n"); +	switch ( mode ) +	{ +		case SCREEN_MODE_80x25: +			{ +			} +			break; +		default: +			printf("Unknown screen mode\n"); +	} +	 +	return ret; +} + +int term_print( term_screen *ts, const char *s, size_t n) +{ +	int ret=0; + +	if ( ts == NULL ) +		return -1; + +	if ( s == NULL ) +		return -1; + +	if ( n < 1 ) +		return -1; + +	if ( n > 80*25 ) +		return -1; + +	ret = write( ts->ofd, s, n ); + +	return ret; +} + +//print data to terminal starting from x,y +int term_print_xy( term_screen *ts, const char *buf, size_t size,  +	int init_column, int init_row ) +{ +	int ret=-1; +	if ( buf == NULL ) +	{ +		return -1; +	} + +	if ( size <= 0 ) +	{ +		return -1; +	} + +	switch ( ts->mode ) +	{ +		case SCREEN_MODE_80x25: +			{ +				 +			} +			break; +		default: +			printf("Unknown mode\n"); +	} + +	return ret; +} + +int term_draw_hline( term_screen *ts, int pc, int pr, const int sz, char ch) +{ +	int ret=0; +	char buf[sz]; memset( buf, ch, sz ); + +	if ( sz > 0) +	{ +		term_cur_set_c( ts, pc ); +		term_cur_set_r( ts, pr ); +		write( ts->ofd, buf, sz ); +	} else +	{ +		ret = -1; +	} + +	return ret; +} + +//read one character from stream +int term_getc( term_screen *ts ) +{ +	int ret=-1; +	int fret=-1; +	char buf; + +	fret = read( ts->ifd, &buf, 1 ); +	if ( fret == 1 ) +	{ +		ret = buf; +	} +	return ret; +} + +int64_t term_getb( term_screen *ts ) +{ +	int64_t ret = -1; +	int fret = -1; +	unsigned char buf[8]; +	 +	fret = read( ts->ifd, buf, 8 ); +	if ( fret == 1 ) +	{ +		//printf("1\n"); + +		ret = buf[0]; +	} else if ( fret == 2 ) +	{ +		uint32_t a1 = buf[0]&0xff; +		uint32_t a2 = buf[1]&0xff; +		uint32_t r = 0x0; + +		r = (a1+((a2<<8)&0xff)); + +		ret = r; + +	} else if ( fret == 3 ) +	{ +		uint32_t a1 = buf[0]&0xff; +		uint32_t a2 = buf[1]&0xff; +		uint32_t a3 = buf[2]&0xff; +		uint32_t r=0x0; + +		//printf("3\n"); + +		r = (a1+((a2<<8)&0xFF00)+((a3<<16)&0xFF0000)); + +		ret = r; +	} else if ( fret == 4) +	{ +		uint32_t a1 = buf[0]&0xff; +		uint32_t a2 = buf[1]&0xff; +		uint32_t a3 = buf[2]&0xff; +		uint32_t a4 = buf[3]&0xff; +		uint32_t r=0x0; + +		//printf("4\n"); + +		r = (a1+((a2<<8)&0xFF00)+((a3<<16)&0xFF0000)+((a4<<24)&(0xFF000000))); + +		ret = r; +	} else if ( fret == 5 ) +	{ +		uint64_t a1 = buf[0]&0xff; +		uint64_t a2 = buf[1]&0xff; +		uint64_t a3 = buf[2]&0xff; +		uint64_t a4 = buf[3]&0xff; +		uint64_t a5 = buf[4]&0xff; +		uint64_t r=0x0; + +		//printf("5 %02x %02x %02x %02x %02x\n",a1,a2,a3,a4,a5); + +		r = (a1+ +			((a2<<8)&0xFF00)+ +			((a3<<16)&0xFF0000)+ +			((a4<<24)&0xFF000000)+ +			((a5<<32)&0xFF00000000)); + +		ret = r; +	} else +	{ +		int i; +		for (i=0;i<fret;i++) +			printf("!%02x",buf[fret-i-1]); +		printf(" ![%d]",fret); +		ret = 0; +	} + + +	return ret; +} + +int term_putc( term_screen *ts, char c ) +{ +	int ret = 0; +	int fret = -1; + +	fret = write( ts->ofd, &c, 1 ); +	if ( fret != 1 ) +	{ +		ret = -1; +	} + +	return ret; +} + +//return amoutn fo characters readed +//on error or if nothing is imputed 0 returned +int term_readline( term_screen *ts, char *str, size_t str_size, int flag ) +{ +	int ret = 0; +	int max_row, max_column; +	char *buf = NULL; +	int buf_size = str_size-1; +	int buf_curent = 0; +	int menu_input=0; +	char menu_cmd = 0; +	int orig_row; +	int orig_col; + +	buf = malloc( buf_size ); +	memset( buf, 0, buf_size ); + +	max_row = term_get_maxrow( ts ); +	max_column = term_get_maxcol( ts ); +	orig_row = term_cur_get_r( ts ); +	orig_col = term_cur_get_c( ts ); + +	menu_cmd = 0; +	buf_curent = 0; +	//finsih when escape button is setted +	while ( menu_cmd != TK_ESC ) +	{ +		menu_input = term_getc( ts ); +		if ( menu_input != -1 ) +		{ +			menu_cmd = (char)menu_input; +			//add to buffer any printable alpahnumeric char +			if ( isalpha( menu_cmd ) &&  +				(flag == READLINE_TEXT || flag == READLINE_ALPHA  +				|| flag == READLINE_HIDDEN) ) +			{ +				if ( buf_curent < buf_size ) +				{ +					buf[ buf_curent ] = menu_cmd; +					buf_curent += 1; +				} +			//add to buffer number 0-9 +			} else if ( isdigit( menu_cmd ) && +				( flag == READLINE_TEXT || flag == READLINE_NUMBER  +				|| flag == READLINE_HIDDEN )) +			{ +				if ( buf_curent < buf_size ) +				{ +					buf[ buf_curent ] = menu_cmd; +					buf_curent += 1; +				} +			//if space allowed +			} else if ( (menu_cmd == ' ') && (flag == READLINE_TEXT) ) +			{ +				if ( buf_curent < buf_size ) +				{ +					buf[ buf_curent ] = menu_cmd; +					buf_curent += 1; +				} +			//remaining printable chars for READLINE_TEXT +			} else if ( ispunct( menu_cmd ) && +				(flag == READLINE_TEXT )) +			{ +				if ( buf_curent < buf_size ) +				{ +					buf[ buf_curent ] = menu_cmd; +					buf_curent += 1; +				} +			//deleteone char from buffer with backspace +			} else if ( menu_cmd == TK_BACKSPACE ) +			{ +				if ( buf_curent > 0) +				{ +					buf[ buf_curent ] = 0x0; +					buf_curent -= 1; +				} +			//input ready lets finish input +			} else if ( menu_cmd == TK_ENTER ) +			{ +				ret = buf_curent; +				memcpy( str, buf, buf_size ); +				str[ str_size-1 ] = 0x0; +				break; +			//finsih input without saving result +			} else if ( menu_cmd == TK_ESC ) +			{ +				ret = -1; +			} + +			{ +				int i; +				term_cur_set_r( ts, orig_row ); +				term_cur_set_c( ts, orig_col ); +				for (i=0;i<buf_size;i++) +				{ +					if ( i < buf_curent ) +					{ +						if ( (flag == READLINE_TEXT) || (flag == READLINE_ALPHA)  +							|| (flag == READLINE_NUMBER) ) +						{ +							term_putc( ts, buf[i] ); +						} else if ( flag == READLINE_HIDDEN ) +						{ +							term_putc( ts, '*'); +						} +					} else +					{ +						term_putc( ts, ' ' ); +					} +				} +				term_cur_set_c( ts, orig_col+buf_curent ); +				term_cur_set_r( ts, orig_row ); +			} +		} +	} + +	if ( buf != NULL) +	{ +		free( buf ); +		buf = NULL; +	} + +	return ret; +} + +//this is to replace printf,flush code +int term_printf( term_screen *ts, const char *format, ...) +{ +	int ret=0; + +	va_list args; +	va_start(args, format); + +	vdprintf(ts->ofd, format, args); + +	va_end(args); + +	return ret; +} | 
