X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Ftinfo_driver.c;h=c28d76415549dfa5ad65dd4c569cc1b440ec7856;hp=477cbbc24f37221b5742c954660a4990bc8fa8c2;hb=56a81c7e79f73d397cc8074401d039f59c34cad5;hpb=3eda6f30a84d53844d2ebceadb457e2e7e9cfbf3 diff --git a/ncurses/tinfo/tinfo_driver.c b/ncurses/tinfo/tinfo_driver.c index 477cbbc2..c28d7641 100644 --- a/ncurses/tinfo/tinfo_driver.c +++ b/ncurses/tinfo/tinfo_driver.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 2008-2016,2017 Free Software Foundation, Inc. * + * Copyright 2018-2019,2020 Thomas E. Dickey * + * Copyright 2008-2016,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -28,11 +29,11 @@ /**************************************************************************** * Author: Juergen Pfeifer * - * * + * and: Thomas E. Dickey * ****************************************************************************/ #include -#define CUR ((TERMINAL*)TCB)->type. +#define CUR TerminalType((TERMINAL*)TCB). #include #include /* ospeed */ @@ -51,7 +52,7 @@ # endif #endif -MODULE_ID("$Id: tinfo_driver.c,v 1.47 2017/03/28 09:15:24 tom Exp $") +MODULE_ID("$Id: tinfo_driver.c,v 1.71 2020/12/12 01:06:40 tom Exp $") /* * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, @@ -115,13 +116,15 @@ drv_Name(TERMINAL_CONTROL_BLOCK * TCB) } static void -get_baudrate(TERMINAL * termp) +get_baudrate(TERMINAL *termp) { int my_ospeed; int result; if (GET_TTY(termp->Filedes, &termp->Nttyb) == OK) { #ifdef TERMIOS termp->Nttyb.c_oflag &= (unsigned) (~OFLAGS_TABS); +#elif defined(EXP_WIN32_DRIVER) + /* noop */ #else termp->Nttyb.sg_flags &= (unsigned) (~XTABS); #endif @@ -132,6 +135,9 @@ get_baudrate(TERMINAL * termp) #else /* !USE_OLD_TTY */ #ifdef TERMIOS my_ospeed = (NCURSES_OSPEED) cfgetospeed(&(termp->Nttyb)); +#elif defined(EXP_WIN32_DRIVER) + /* noop */ + my_ospeed = 0; #else my_ospeed = (NCURSES_OSPEED) termp->Nttyb.sg_ospeed; #endif @@ -144,6 +150,8 @@ get_baudrate(TERMINAL * termp) #undef SETUP_FAIL #define SETUP_FAIL FALSE +#define NO_COPY {} + static bool drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) { @@ -161,17 +169,20 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) TCB->magic = TCBMAGIC; #if (NCURSES_USE_DATABASE || NCURSES_USE_TERMCAP) - status = _nc_setup_tinfo(tname, &termp->type); + status = _nc_setup_tinfo(tname, &TerminalType(termp)); + T(("_nc_setup_tinfo returns %d", status)); #else + T(("no database available")); status = TGETENT_NO; #endif /* try fallback list if entry on disk */ if (status != TGETENT_YES) { - const TERMTYPE *fallback = _nc_fallback(tname); + const TERMTYPE2 *fallback = _nc_fallback2(tname); if (fallback) { - termp->type = *fallback; + T(("found fallback entry")); + TerminalType(termp) = *fallback; status = TGETENT_YES; } } @@ -181,14 +192,18 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) if (status == TGETENT_ERR) { ret_error0(status, "terminals database is inaccessible\n"); } else if (status == TGETENT_NO) { - ret_error1(status, "unknown terminal type.\n", tname); + ret_error1(status, "unknown terminal type.\n", + tname, NO_COPY); + } else { + ret_error0(status, "unexpected return-code\n"); } } result = TRUE; +#if NCURSES_EXT_NUMBERS + _nc_export_termtype2(&termp->type, &TerminalType(termp)); +#endif #if !USE_REENTRANT -#define MY_SIZE (size_t) NAMESIZE - 1 - _nc_STRNCPY(ttytype, termp->type.term_names, MY_SIZE); - ttytype[MY_SIZE] = '\0'; + save_ttytype(termp); #endif if (command_character) @@ -203,6 +218,14 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) if (sp == 0 && NC_ISATTY(termp->Filedes)) { get_baudrate(termp); } +#if NCURSES_EXT_NUMBERS +#define cleanup_termtype() \ + _nc_free_termtype2(&TerminalType(termp)); \ + _nc_free_termtype(&termp->type) +#else +#define cleanup_termtype() \ + _nc_free_termtype2(&TerminalType(termp)) +#endif if (generic_type) { /* @@ -212,13 +235,19 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) if ((VALID_STRING(cursor_address) || (VALID_STRING(cursor_down) && VALID_STRING(cursor_home))) && VALID_STRING(clear_screen)) { - ret_error1(TGETENT_YES, "terminal is not really generic.\n", tname); + cleanup_termtype(); + ret_error1(TGETENT_YES, "terminal is not really generic.\n", + tname, NO_COPY); } else { - ret_error1(TGETENT_NO, "I need something more specific.\n", tname); + cleanup_termtype(); + ret_error1(TGETENT_NO, "I need something more specific.\n", + tname, NO_COPY); } } if (hard_copy) { - ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname); + cleanup_termtype(); + ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", + tname, NO_COPY); } returnBool(result); @@ -332,23 +361,23 @@ drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB, if (set_a_foreground) { TPUTS_TRACE("set_a_foreground"); NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx - TPARM_1(set_a_foreground, color), 1, outc); + TIPARM_1(set_a_foreground, color), 1, outc); } else { TPUTS_TRACE("set_foreground"); NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx - TPARM_1(set_foreground, - toggled_colors(color)), 1, outc); + TIPARM_1(set_foreground, + toggled_colors(color)), 1, outc); } } else { if (set_a_background) { TPUTS_TRACE("set_a_background"); NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx - TPARM_1(set_a_background, color), 1, outc); + TIPARM_1(set_a_background, color), 1, outc); } else { TPUTS_TRACE("set_background"); NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx - TPARM_1(set_background, - toggled_colors(color)), 1, outc); + TIPARM_1(set_background, + toggled_colors(color)), 1, outc); } } } @@ -403,12 +432,19 @@ drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *linep, int *colp) useTioctl = _nc_prescreen.use_tioctl; } +#ifdef EXP_WIN32_DRIVER + /* If we are here, then Windows console is used in terminfo mode. + We need to figure out the size using the console API + */ + _nc_console_size(linep, colp); + T(("screen size: winconsole lines = %d columns = %d", *linep, *colp)); +#else /* figure out the size of the screen */ T(("screen size: terminfo lines = %d columns = %d", lines, columns)); *linep = (int) lines; *colp = (int) columns; - +#endif if (useEnv || useTioctl) { int value; @@ -578,6 +614,8 @@ drv_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag) if ((drv_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) { #ifdef TERMIOS _term->Nttyb.c_oflag &= (unsigned) ~OFLAGS_TABS; +#elif defined(EXP_WIN32_DRIVER) + /* noop */ #else _term->Nttyb.sg_flags &= (unsigned) ~XTABS; #endif @@ -603,6 +641,8 @@ drv_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag) #ifdef TERMIOS if (_term->Ottyb.c_oflag & OFLAGS_TABS) tab = back_tab = NULL; +#elif defined(EXP_WIN32_DRIVER) + /* noop */ #else if (_term->Ottyb.sg_flags & XTABS) tab = back_tab = NULL; @@ -740,10 +780,10 @@ drv_initpair(TERMINAL_CONTROL_BLOCK * TCB, int pair, int f, int b) tp[b].red, tp[b].green, tp[b].blue)); NCURSES_PUTP2("initialize_pair", - TPARM_7(initialize_pair, - pair, - tp[f].red, tp[f].green, tp[f].blue, - tp[b].red, tp[b].green, tp[b].blue)); + TIPARM_7(initialize_pair, + pair, + tp[f].red, tp[f].green, tp[f].blue, + tp[b].red, tp[b].green, tp[b].blue)); } } @@ -776,7 +816,7 @@ drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB, AssertTCB(); if (initialize_color != NULL) { NCURSES_PUTP2("initialize_color", - TPARM_4(initialize_color, color, r, g, b)); + TIPARM_4(initialize_color, color, r, g, b)); } } @@ -802,7 +842,7 @@ drv_do_color(TERMINAL_CONTROL_BLOCK * TCB, if (set_color_pair) { TPUTS_TRACE("set_color_pair"); NCURSES_SP_NAME(tputs) (NCURSES_SP_ARGx - TPARM_1(set_color_pair, pair), 1, outc); + TIPARM_1(set_color_pair, pair), 1, outc); return; } else if (sp != 0) { _nc_pair_content(SP_PARM, pair, &fg, &bg); @@ -882,12 +922,9 @@ drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB) /* we know how to recognize mouse events under "xterm" */ if (sp != 0) { - if (key_mouse != 0) { - if (!strcmp(key_mouse, xterm_kmous) - || strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { - init_xterm_mouse(sp); - } - } else if (strstr(TerminalOf(sp)->type.term_names, "xterm") != 0) { + if (NonEmpty(key_mouse)) { + init_xterm_mouse(sp); + } else if (strstr(SP_TERMTYPE term_names, "xterm") != 0) { if (_nc_add_to_try(&(sp->_keytry), xterm_kmous, KEY_MOUSE) == OK) init_xterm_mouse(sp); } @@ -912,11 +949,18 @@ drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB, } else #endif { +#ifdef EXP_WIN32_DRIVER + rc = _nc_console_testmouse(sp, + _nc_console_handle(sp->_ifd), + delay + EVENTLIST_2nd(evl)); +#else rc = TCBOf(sp)->drv->td_twait(TCBOf(sp), TWAIT_MASK, delay, (int *) 0 EVENTLIST_2nd(evl)); +#endif #if USE_SYSMOUSE if ((sp->_mouse_type == M_SYSMOUSE) && (sp->_sysmouse_head < sp->_sysmouse_tail) @@ -1012,12 +1056,18 @@ drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB) { AssertTCB(); - clear_screen = 0; - cursor_down = parm_down_cursor = 0; - cursor_address = 0; - cursor_up = parm_up_cursor = 0; - row_address = 0; - cursor_home = carriage_return; + /* *INDENT-EQLS* */ + clear_screen = ABSENT_STRING; + cursor_address = ABSENT_STRING; + cursor_down = ABSENT_STRING; + cursor_up = ABSENT_STRING; + parm_down_cursor = ABSENT_STRING; + parm_up_cursor = ABSENT_STRING; + row_address = ABSENT_STRING; + cursor_home = carriage_return; + + if (back_color_erase) + clr_eos = ABSENT_STRING; } static void @@ -1064,8 +1114,13 @@ drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *real_map, chtype *fake_map) while (i + 1 < length) { if (acs_chars[i] != 0 && UChar(acs_chars[i]) < ACS_LEN) { real_map[UChar(acs_chars[i])] = UChar(acs_chars[i + 1]) | A_ALTCHARSET; - if (sp != 0) + T(("#%d real_map[%s] = %s", + (int) i, + _tracechar(UChar(acs_chars[i])), + _tracechtype(real_map[UChar(acs_chars[i])]))); + if (sp != 0) { sp->_screen_acs_map[UChar(acs_chars[i])] = TRUE; + } } i += 2; } @@ -1095,7 +1150,6 @@ drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *real_map, chtype *fake_map) ? "DIFF" : "SAME"), _nc_visbuf(show)); - _nc_unlock_global(tracef); } #endif /* TRACE */ @@ -1204,16 +1258,25 @@ drv_twait(TERMINAL_CONTROL_BLOCK * TCB, AssertTCB(); SetSP(); - +#ifdef EXP_WIN32_DRIVER + return _nc_console_twait(sp, + _nc_console_handle(sp->_ifd), + mode, + milliseconds, + timeleft EVENTLIST_2nd(evl)); +#else return _nc_timed_wait(sp, mode, milliseconds, timeleft EVENTLIST_2nd(evl)); +#endif } static int drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) { SCREEN *sp; - unsigned char c2 = 0; int n; +#ifndef EXP_WIN32_DRIVER + unsigned char c2 = 0; +#endif AssertTCB(); assert(buf); @@ -1223,11 +1286,19 @@ drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) if ((pthread_self) && (pthread_kill) && (pthread_equal)) _nc_globals.read_thread = pthread_self(); # endif +#ifdef EXP_WIN32_DRIVER + n = _nc_console_read(sp, + _nc_console_handle(sp->_ifd), + buf); +#else n = (int) read(sp->_ifd, &c2, (size_t) 1); +#endif #if USE_PTHREADS_EINTR _nc_globals.read_thread = 0; #endif +#ifndef EXP_WIN32_DRIVER *buf = (int) c2; +#endif return n; } @@ -1244,6 +1315,8 @@ drv_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms) request = remaining; } } +#elif defined(EXP_WIN32_DRIVER) + Sleep((DWORD) ms); #else _nc_timed_wait(0, 0, ms, (int *) 0 EVENTLIST_2nd(0)); #endif @@ -1312,23 +1385,29 @@ drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int c, int flag) unsigned ch = (unsigned) c; if (flag) { while ((s = _nc_expand_try(sp->_key_ok, - ch, &count, (size_t) 0)) != 0 - && _nc_remove_key(&(sp->_key_ok), ch)) { - code = _nc_add_to_try(&(sp->_keytry), s, ch); - free(s); - count = 0; - if (code != OK) - break; + ch, &count, (size_t) 0)) != 0) { + if (_nc_remove_key(&(sp->_key_ok), ch)) { + code = _nc_add_to_try(&(sp->_keytry), s, ch); + free(s); + count = 0; + if (code != OK) + break; + } else { + free(s); + } } } else { while ((s = _nc_expand_try(sp->_keytry, - ch, &count, (size_t) 0)) != 0 - && _nc_remove_key(&(sp->_keytry), ch)) { - code = _nc_add_to_try(&(sp->_key_ok), s, ch); - free(s); - count = 0; - if (code != OK) - break; + ch, &count, (size_t) 0)) != 0) { + if (_nc_remove_key(&(sp->_keytry), ch)) { + code = _nc_add_to_try(&(sp->_key_ok), s, ch); + free(s); + count = 0; + if (code != OK) + break; + } else { + free(s); + } } } } @@ -1415,3 +1494,66 @@ NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_TINFO_DRIVER = { drv_kyExist, /* kyExist */ drv_cursorSet /* cursorSet */ }; + +#ifdef EXP_WIN32_DRIVER +/* + * The terminfo driver is mandatory and must always be present. + * So this is the natural place for the driver initialisation + * logic. + */ + +typedef struct DriverEntry { + const char *name; + TERM_DRIVER *driver; +} DRIVER_ENTRY; + +static DRIVER_ENTRY DriverTable[] = +{ +#ifdef _NC_WINDOWS + {"win32console", &_nc_WIN_DRIVER}, +#endif + {"tinfo", &_nc_TINFO_DRIVER} /* must be last */ +}; + +NCURSES_EXPORT(int) +_nc_get_driver(TERMINAL_CONTROL_BLOCK * TCB, const char *name, int *errret) +{ + int code = ERR; + size_t i; + TERM_DRIVER *res = (TERM_DRIVER *) 0; + TERM_DRIVER *use = 0; + + T((T_CALLED("_nc_get_driver(%p, %s, %p)"), + (void *) TCB, NonNull(name), (void *) errret)); + + assert(TCB != 0); + + for (i = 0; i < SIZEOF(DriverTable); i++) { + res = DriverTable[i].driver; +#ifdef _NC_WINDOWS + if ((i + 1) == SIZEOF(DriverTable)) { + /* For Windows >= 10.0.17763 Windows Console interface implements + virtual Terminal functionality. + If on Windows td_CanHandle returned FALSE although the terminal + name is empty, we default to ms-terminal as tinfo TERM type. + */ + if (name == 0 || *name == 0 || (strcmp(name, "unknown") == 0)) { + name = MS_TERMINAL; + T(("Set TERM=%s", name)); + } + } +#endif + if (strcmp(DriverTable[i].name, res->td_name(TCB)) == 0) { + if (res->td_CanHandle(TCB, name, errret)) { + use = res; + break; + } + } + } + if (use != 0) { + TCB->drv = use; + code = OK; + } + returnCode(code); +} +#endif /* EXP_WIN32_DRIVER */