aboutsummaryrefslogtreecommitdiffstats
path: root/libterm/term.c
diff options
context:
space:
mode:
Diffstat (limited to 'libterm/term.c')
-rw-r--r--libterm/term.c361
1 files changed, 361 insertions, 0 deletions
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