X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Firssi%2Fsrc%2Ffe-text%2Fterminfo-core.c;fp=apps%2Firssi%2Fsrc%2Ffe-text%2Fterminfo-core.c;h=0000000000000000000000000000000000000000;hb=72c2de619079457f7a68100eb13385275a424a23;hp=530050c2a4200c66a10b2792d5d6299449930daf;hpb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;p=runtime.git diff --git a/apps/irssi/src/fe-text/terminfo-core.c b/apps/irssi/src/fe-text/terminfo-core.c deleted file mode 100644 index 530050c2..00000000 --- a/apps/irssi/src/fe-text/terminfo-core.c +++ /dev/null @@ -1,657 +0,0 @@ -#include "module.h" -#include "signals.h" -#include "terminfo-core.h" - -#ifndef _POSIX_VDISABLE -# define _POSIX_VDISABLE 0 -#endif - -#define tput(s) tputs(s, 0, term_putchar) -inline static int term_putchar(int c) -{ - return fputc(c, current_term->out); -} - -/* Don't bother including curses.h because of these - - they might not even be defined there */ -char *tparm(); -int tputs(); - -#ifdef HAVE_TERMINFO -int setupterm(); -char *tigetstr(); -int tigetnum(); -int tigetflag(); -#define term_getstr(x, buffer) tigetstr(x.ti_name) -#define term_getnum(x) tigetnum(x.ti_name); -#define term_getflag(x) tigetflag(x.ti_name); -#else -int tgetent(); -char *tgetstr(); -int tgetnum(); -int tgetflag(); -#define term_getstr(x, buffer) tgetstr(x.tc_name, &buffer) -#define term_getnum(x) tgetnum(x.tc_name) -#define term_getflag(x) tgetflag(x.tc_name) -#endif - -#define CAP_TYPE_FLAG 0 -#define CAP_TYPE_INT 1 -#define CAP_TYPE_STR 2 - -typedef struct { - const char *ti_name; /* terminfo name */ - const char *tc_name; /* termcap name */ - int type; - void *ptr; -} TERMINFO_REC; - -TERM_REC *current_term; -static TERM_REC temp_term; /* not really used for anything */ - -/* Define only what we might need */ -static TERMINFO_REC tcaps[] = { - /* Terminal size */ - { "cols", "co", CAP_TYPE_INT, &temp_term.width }, - { "lines", "li", CAP_TYPE_INT, &temp_term.height }, - - /* Cursor movement */ - { "smcup", "ti", CAP_TYPE_STR, &temp_term.TI_smcup }, - { "rmcup", "te", CAP_TYPE_STR, &temp_term.TI_rmcup }, - { "cup", "cm", CAP_TYPE_STR, &temp_term.TI_cup }, - { "hpa", "ch", CAP_TYPE_STR, &temp_term.TI_hpa }, - { "vpa", "vh", CAP_TYPE_STR, &temp_term.TI_vpa }, - { "cub1", "le", CAP_TYPE_STR, &temp_term.TI_cub1 }, - { "cuf1", "nd", CAP_TYPE_STR, &temp_term.TI_cuf1 }, - { "civis", "vi", CAP_TYPE_STR, &temp_term.TI_civis }, - { "cnorm", "ve", CAP_TYPE_STR, &temp_term.TI_cnorm }, - - /* Scrolling */ - { "csr", "cs", CAP_TYPE_STR, &temp_term.TI_csr }, - { "wind", "wi", CAP_TYPE_STR, &temp_term.TI_wind }, - { "ri", "sr", CAP_TYPE_STR, &temp_term.TI_ri }, - { "rin", "SR", CAP_TYPE_STR, &temp_term.TI_rin }, - { "ind", "sf", CAP_TYPE_STR, &temp_term.TI_ind }, - { "indn", "SF", CAP_TYPE_STR, &temp_term.TI_indn }, - { "il", "AL", CAP_TYPE_STR, &temp_term.TI_il }, - { "il1", "al", CAP_TYPE_STR, &temp_term.TI_il1 }, - { "dl", "DL", CAP_TYPE_STR, &temp_term.TI_dl }, - { "dl1", "dl", CAP_TYPE_STR, &temp_term.TI_dl1 }, - - /* Clearing screen */ - { "clear", "cl", CAP_TYPE_STR, &temp_term.TI_clear }, - { "ed", "cd", CAP_TYPE_STR, &temp_term.TI_ed }, - - /* Clearing to end of line */ - { "el", "ce", CAP_TYPE_STR, &temp_term.TI_el }, - - /* Repeating character */ - { "rep", "rp", CAP_TYPE_STR, &temp_term.TI_rep }, - - /* Colors */ - { "sgr0", "me", CAP_TYPE_STR, &temp_term.TI_sgr0 }, - { "smul", "us", CAP_TYPE_STR, &temp_term.TI_smul }, - { "rmul", "ue", CAP_TYPE_STR, &temp_term.TI_rmul }, - { "smso", "so", CAP_TYPE_STR, &temp_term.TI_smso }, - { "rmso", "se", CAP_TYPE_STR, &temp_term.TI_rmso }, - { "bold", "md", CAP_TYPE_STR, &temp_term.TI_bold }, - { "blink", "mb", CAP_TYPE_STR, &temp_term.TI_blink }, - { "setaf", "AF", CAP_TYPE_STR, &temp_term.TI_setaf }, - { "setab", "AB", CAP_TYPE_STR, &temp_term.TI_setab }, - { "setf", "Sf", CAP_TYPE_STR, &temp_term.TI_setf }, - { "setb", "Sb", CAP_TYPE_STR, &temp_term.TI_setb }, - - /* Beep */ - { "bel", "bl", CAP_TYPE_STR, &temp_term.TI_bel }, -}; - -/* Move cursor (cursor_address / cup) */ -static void _move_cup(TERM_REC *term, int x, int y) -{ - tput(tparm(term->TI_cup, y, x)); -} - -/* Move cursor (column_address+row_address / hpa+vpa) */ -static void _move_pa(TERM_REC *term, int x, int y) -{ - tput(tparm(term->TI_hpa, x)); - tput(tparm(term->TI_vpa, y)); -} - -/* Move cursor from a known position */ -static void _move_relative(TERM_REC *term, int oldx, int oldy, int x, int y) -{ - if (oldx == 0 && x == 0 && y == oldy+1) { - /* move to beginning of next line - - hope this works everywhere */ - tput("\r\n"); - return; - } - - if (oldx > 0 && y == oldy) { - /* move cursor left/right */ - if (x == oldx-1 && term->TI_cub1) { - tput(tparm(term->TI_cub1)); - return; - } - if (x == oldx+1 && y == oldy && term->TI_cuf1) { - tput(tparm(term->TI_cuf1)); - return; - } - } - - /* fallback to absolute positioning */ - if (term->TI_cup) { - tput(tparm(term->TI_cup, y, x)); - return; - } - - if (oldy != y) - tput(tparm(term->TI_vpa, y)); - if (oldx != x) - tput(tparm(term->TI_hpa, x)); -} - -/* Set cursor visible/invisible */ -static void _set_cursor_visible(TERM_REC *term, int set) -{ - tput(tparm(set ? term->TI_cnorm : term->TI_civis)); -} - -#define scroll_region_setup(term, y1, y2) \ - if ((term)->TI_csr != NULL) \ - tput(tparm((term)->TI_csr, y1, y2)); \ - else if ((term)->TI_wind != NULL) \ - tput(tparm((term)->TI_wind, y1, y2, 0, (term)->width-1)); - -/* Scroll (change_scroll_region+parm_rindex+parm_index / csr+rin+indn) */ -static void _scroll_region(TERM_REC *term, int y1, int y2, int count) -{ - /* setup the scrolling region to wanted area */ - scroll_region_setup(term, y1, y2); - - term->move(term, 0, y1); - if (count > 0) { - term->move(term, 0, y2); - tput(tparm(term->TI_indn, count, count)); - } else if (count < 0) { - term->move(term, 0, y1); - tput(tparm(term->TI_rin, -count, -count)); - } - - /* reset the scrolling region to full screen */ - scroll_region_setup(term, 0, term->height-1); -} - -/* Scroll (change_scroll_region+scroll_reverse+scroll_forward / csr+ri+ind) */ -static void _scroll_region_1(TERM_REC *term, int y1, int y2, int count) -{ - int i; - - /* setup the scrolling region to wanted area */ - scroll_region_setup(term, y1, y2); - - if (count > 0) { - term->move(term, 0, y2); - for (i = 0; i < count; i++) - tput(tparm(term->TI_ind)); - } else if (count < 0) { - term->move(term, 0, y1); - for (i = count; i < 0; i++) - tput(tparm(term->TI_ri)); - } - - /* reset the scrolling region to full screen */ - scroll_region_setup(term, 0, term->height-1); -} - -/* Scroll (parm_insert_line+parm_delete_line / il+dl) */ -static void _scroll_line(TERM_REC *term, int y1, int y2, int count) -{ - /* setup the scrolling region to wanted area - - this might not necessarily work with il/dl, but at least it - looks better if it does */ - scroll_region_setup(term, y1, y2); - - if (count > 0) { - term->move(term, 0, y1); - tput(tparm(term->TI_dl, count, count)); - term->move(term, 0, y2-count+1); - tput(tparm(term->TI_il, count, count)); - } else if (count < 0) { - term->move(term, 0, y2+count+1); - tput(tparm(term->TI_dl, -count, -count)); - term->move(term, 0, y1); - tput(tparm(term->TI_il, -count, -count)); - } - - /* reset the scrolling region to full screen */ - scroll_region_setup(term, 0, term->height-1); -} - -/* Scroll (insert_line+delete_line / il1+dl1) */ -static void _scroll_line_1(TERM_REC *term, int y1, int y2, int count) -{ - int i; - - if (count > 0) { - term->move(term, 0, y1); - for (i = 0; i < count; i++) - tput(tparm(term->TI_dl1)); - term->move(term, 0, y2-count+1); - for (i = 0; i < count; i++) - tput(tparm(term->TI_il1)); - } else if (count < 0) { - term->move(term, 0, y2+count+1); - for (i = count; i < 0; i++) - tput(tparm(term->TI_dl1)); - term->move(term, 0, y1); - for (i = count; i < 0; i++) - tput(tparm(term->TI_il1)); - } -} - -/* Clear screen (clear_screen / clear) */ -static void _clear_screen(TERM_REC *term) -{ - tput(tparm(term->TI_clear)); -} - -/* Clear screen (clr_eos / ed) */ -static void _clear_eos(TERM_REC *term) -{ - term->move(term, 0, 0); - tput(tparm(term->TI_ed)); -} - -/* Clear screen (parm_delete_line / dl) */ -static void _clear_del(TERM_REC *term) -{ - term->move(term, 0, 0); - tput(tparm(term->TI_dl, term->height, term->height)); -} - -/* Clear screen (delete_line / dl1) */ -static void _clear_del_1(TERM_REC *term) -{ - int i; - - term->move(term, 0, 0); - for (i = 0; i < term->height; i++) - tput(tparm(term->TI_dl1)); -} - -/* Clear to end of line (clr_eol / el) */ -static void _clrtoeol(TERM_REC *term) -{ - tput(tparm(term->TI_el)); -} - -/* Repeat character (rep / rp) */ -static void _repeat(TERM_REC *term, int chr, int count) -{ - tput(tparm(term->TI_rep, chr, count)); -} - -/* Repeat character (manual) */ -static void _repeat_manual(TERM_REC *term, int chr, int count) -{ - while (count > 0) { - putc(chr, term->out); - count--; - } -} - -/* Reset all terminal attributes */ -static void _set_normal(TERM_REC *term) -{ - tput(tparm(term->TI_normal)); -} - -/* Bold on */ -static void _set_bold(TERM_REC *term) -{ - tput(tparm(term->TI_bold)); -} - -/* Underline on/off */ -static void _set_uline(TERM_REC *term, int set) -{ - tput(tparm(set ? term->TI_smul : term->TI_rmul)); -} - -/* Standout on/off */ -static void _set_standout(TERM_REC *term, int set) -{ - tput(tparm(set ? term->TI_smso : term->TI_rmso)); -} - -/* Change foreground color */ -static void _set_fg(TERM_REC *term, int color) -{ - tput(tparm(term->TI_fg[color & 0x0f])); -} - -/* Change background color */ -static void _set_bg(TERM_REC *term, int color) -{ - tput(tparm(term->TI_bg[color & 0x0f])); -} - -/* Beep */ -static void _beep(TERM_REC *term) -{ - tput(tparm(term->TI_bel)); -} - -static void _ignore(TERM_REC *term) -{ -} - -static void _ignore_parm(TERM_REC *term, int param) -{ -} - -static void term_fill_capabilities(TERM_REC *term) -{ - int i, ival; - char *sval; - void *ptr; - -#ifndef HAVE_TERMINFO - char *tptr = term->buffer2; -#endif - for (i = 0; i < sizeof(tcaps)/sizeof(tcaps[0]); i++) { - ptr = (char *) term + (int) ((char *) tcaps[i].ptr - (char *) &temp_term); - - switch (tcaps[i].type) { - case CAP_TYPE_FLAG: - ival = term_getflag(tcaps[i]); - *(int *)ptr = ival; - break; - case CAP_TYPE_INT: - ival = term_getnum(tcaps[i]); - *(int *)ptr = ival; - break; - case CAP_TYPE_STR: - sval = term_getstr(tcaps[i], tptr); - if (sval == (char *) -1) - *(char **)ptr = NULL; - else - *(char **)ptr = sval; - break; - } - } -} - -/* Terminal was resized - ask the width/height from terminfo again */ -void terminfo_resize(TERM_REC *term) -{ - /* FIXME: is this possible? */ -} - -static void terminfo_colors_deinit(TERM_REC *term) -{ - int i; - - if (terminfo_is_colors_set(term)) { - for (i = 0; i < 16; i++) { - g_free(term->TI_fg[i]); - g_free(term->TI_bg[i]); - } - - memset(term->TI_fg, 0, sizeof(term->TI_fg)); - memset(term->TI_bg, 0, sizeof(term->TI_fg)); - } -} - -/* Setup colors - if force is set, use ANSI-style colors if - terminal capabilities don't contain color codes */ -void terminfo_setup_colors(TERM_REC *term, int force) -{ - static char ansitab[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; - const char *bold, *blink; - int i; - - terminfo_colors_deinit(term); - term->has_colors = term->TI_setf || term->TI_setaf; - - if (term->TI_setaf) { - for (i = 0; i < 8; i++) - term->TI_fg[i] = g_strdup(tparm(term->TI_setaf, ansitab[i], 0)); - } else if (term->TI_setf) { - for (i = 0; i < 8; i++) - term->TI_fg[i] = g_strdup(tparm(term->TI_setf, i, 0)); - } else if (force) { - for (i = 0; i < 8; i++) - term->TI_fg[i] = g_strdup_printf("\033[%dm", 30+ansitab[i]); - } - - if (term->TI_setab) { - for (i = 0; i < 8; i++) - term->TI_bg[i] = g_strdup(tparm(term->TI_setab, ansitab[i], 0)); - } else if (term->TI_setb) { - for (i = 0; i < 8; i++) - term->TI_bg[i] = g_strdup(tparm(term->TI_setb, i, 0)); - } else if (force) { - for (i = 0; i < 8; i++) - term->TI_bg[i] = g_strdup_printf("\033[%dm", 40+ansitab[i]); - } - - if (term->TI_setf || term->TI_setaf || force) { - term->set_fg = _set_fg; - term->set_bg = _set_bg; - - /* bold fg, blink bg */ - bold = term->TI_bold ? term->TI_bold : ""; - for (i = 0; i < 8; i++) - term->TI_fg[i+8] = g_strconcat(bold, term->TI_fg[i], NULL); - - blink = term->TI_blink ? term->TI_blink : ""; - for (i = 0; i < 8; i++) - term->TI_bg[i+8] = g_strconcat(blink, term->TI_bg[i], NULL); - } else { - /* no colors */ - term->set_fg = term->set_bg = _ignore_parm; - } -} - -static void terminfo_input_init(TERM_REC *term) -{ - tcgetattr(fileno(term->in), &term->old_tio); - memcpy(&term->tio, &term->old_tio, sizeof(term->tio)); - - term->tio.c_lflag &= ~(ICANON | ECHO); /* CBREAK, no ECHO */ - term->tio.c_cc[VMIN] = 1; /* read() is satisfied after 1 char */ - term->tio.c_cc[VTIME] = 0; /* No timer */ - - /* Disable INTR, QUIT, VDSUSP and SUSP keys */ - term->tio.c_cc[VINTR] = _POSIX_VDISABLE; - term->tio.c_cc[VQUIT] = _POSIX_VDISABLE; -#ifdef VDSUSP - term->tio.c_cc[VDSUSP] = _POSIX_VDISABLE; -#endif -#ifdef VSUSP - term->tio.c_cc[VSUSP] = _POSIX_VDISABLE; -#endif - - tcsetattr(fileno(term->in), TCSADRAIN, &term->tio); - -} - -static void terminfo_input_deinit(TERM_REC *term) -{ - tcsetattr(fileno(term->in), TCSADRAIN, &term->old_tio); -} - -void terminfo_cont(TERM_REC *term) -{ - if (term->TI_smcup) - tput(tparm(term->TI_smcup)); - terminfo_input_init(term); -} - -void terminfo_stop(TERM_REC *term) -{ - /* reset colors */ - terminfo_set_normal(); - /* move cursor to bottom of the screen */ - terminfo_move(0, term->height-1); - - /* stop cup-mode */ - if (term->TI_rmcup) - tput(tparm(term->TI_rmcup)); - - /* reset input settings */ - terminfo_input_deinit(term); - fflush(term->out); -} - -static int term_setup(TERM_REC *term) -{ - GString *str; -#ifdef HAVE_TERMINFO - int err; -#endif - char *term_env; - - term_env = getenv("TERM"); - if (term_env == NULL) { - fprintf(term->out, "TERM environment not set\n"); - return 0; - } - -#ifdef HAVE_TERMINFO - if (setupterm(term_env, 1, &err) != 0) { - fprintf(term->out, "setupterm() failed for TERM=%s: %d\n", term_env, err); - return 0; - } -#else - if (tgetent(term->buffer1, term_env) < 1) - { - fprintf(term->out, "Termcap not found for TERM=%s\n", term_env); - return 0; - } -#endif - - term_fill_capabilities(term); - - /* Cursor movement */ - if (term->TI_cup) - term->move = _move_cup; - else if (term->TI_hpa && term->TI_vpa) - term->move = _move_pa; - else { - fprintf(term->out, "Terminal doesn't support cursor movement\n"); - return 0; - } - term->move_relative = _move_relative; - term->set_cursor_visible = term->TI_civis && term->TI_cnorm ? - _set_cursor_visible : _ignore_parm; - - /* Scrolling */ - if ((term->TI_csr || term->TI_wind) && term->TI_rin && term->TI_indn) - term->scroll = _scroll_region; - else if (term->TI_il && term->TI_dl) - term->scroll = _scroll_line; - else if ((term->TI_csr || term->TI_wind) && term->TI_ri && term->TI_ind) - term->scroll = _scroll_region_1; - else if (term->scroll == NULL && (term->TI_il1 && term->TI_dl1)) - term->scroll = _scroll_line_1; - else if (term->scroll == NULL) { - fprintf(term->out, "Terminal doesn't support scrolling\n"); - return 0; - } - - /* Clearing screen */ - if (term->TI_clear) - term->clear = _clear_screen; - else if (term->TI_ed) - term->clear = _clear_eos; - else if (term->TI_dl) - term->clear = _clear_del; - else if (term->TI_dl1) - term->clear = _clear_del_1; - else { - /* we could do this by line inserts as well, but don't - bother - if some terminal has insert line it most probably - has delete line as well, if not a regular clear screen */ - fprintf(term->out, "Terminal doesn't support clearing screen\n"); - return 0; - } - - /* Clearing to end of line */ - if (term->TI_el) - term->clrtoeol = _clrtoeol; - else { - fprintf(term->out, "Terminal doesn't support clearing to end of line\n"); - return 0; - } - - /* Repeating character */ - if (term->TI_rep) - term->repeat = _repeat; - else - term->repeat = _repeat_manual; - - /* Bold, underline, standout */ - term->set_bold = term->TI_bold ? _set_bold : _ignore; - term->set_uline = term->TI_smul && term->TI_rmul ? - _set_uline : _ignore_parm; - term->set_standout = term->TI_smso && term->TI_rmso ? - _set_standout : _ignore_parm; - - /* Create a string to set all attributes off */ - str = g_string_new(NULL); - if (term->TI_sgr0) - g_string_append(str, term->TI_sgr0); - if (term->TI_rmul && (term->TI_sgr0 == NULL || strcmp(term->TI_rmul, term->TI_sgr0) != 0)) - g_string_append(str, term->TI_rmul); - if (term->TI_rmso && (term->TI_sgr0 == NULL || strcmp(term->TI_rmso, term->TI_sgr0) != 0)) - g_string_append(str, term->TI_rmso); - term->TI_normal = str->str; - g_string_free(str, FALSE); - term->set_normal = _set_normal; - - term->beep = term->TI_bel ? _beep : _ignore; - - terminfo_setup_colors(term, FALSE); - terminfo_cont(term); - return 1; -} - -TERM_REC *terminfo_core_init(FILE *in, FILE *out) -{ - TERM_REC *old_term, *term; - - old_term = current_term; - current_term = term = g_new0(TERM_REC, 1); - - term->in = in; - term->out = out; - - if (!term_setup(term)) { - g_free(term); - term = NULL; - } - - current_term = old_term; - return term; -} - -void terminfo_core_deinit(TERM_REC *term) -{ - TERM_REC *old_term; - - old_term = current_term; - current_term = term; - term->set_normal(term); - current_term = old_term; - - terminfo_stop(term); - - g_free(term->TI_normal); - terminfo_colors_deinit(term); - - g_free(term); -}