X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Ftinfo_driver.c;h=589df2e036a3beb788a5a026a784ced320921d97;hp=fbd769d5008374df95157d77561c999c94fedc3d;hb=bd257b9d8d715a9a63dab215fcdc53f106e7d050;hpb=c04d54322f7835ed42e597967d8fa5471025fcac diff --git a/ncurses/tinfo/tinfo_driver.c b/ncurses/tinfo/tinfo_driver.c index fbd769d5..589df2e0 100644 --- a/ncurses/tinfo/tinfo_driver.c +++ b/ncurses/tinfo/tinfo_driver.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2008-2009,2010 Free Software Foundation, Inc. * + * Copyright (c) 2008-2010,2011 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 * @@ -50,7 +50,7 @@ # endif #endif -MODULE_ID("$Id: tinfo_driver.c,v 1.7 2010/01/16 16:56:16 tom Exp $") +MODULE_ID("$Id: tinfo_driver.c,v 1.15 2011/08/13 16:11:15 tom Exp $") /* * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, @@ -106,54 +106,6 @@ drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB) return TINFO_DOUPDATE(TCB->csp); } -#define ret_error(code, fmt, arg) if (errret) {\ - *errret = code;\ - return(FALSE); \ - } else {\ - fprintf(stderr, fmt, arg);\ - exit(EXIT_FAILURE);\ - } - -#define ret_error0(code, msg) if (errret) {\ - *errret = code;\ - return(FALSE);\ - } else {\ - fprintf(stderr, msg);\ - exit(EXIT_FAILURE);\ - } - -#if USE_DATABASE || USE_TERMCAP -/* - * Return 1 if entry found, 0 if not found, -1 if database not accessible, - * just like tgetent(). - */ -static int -grab_entry(const char *const tn, TERMTYPE *const tp) -{ - char filename[PATH_MAX]; - int status = _nc_read_entry(tn, filename, tp); - - /* - * If we have an entry, force all of the cancelled strings to null - * pointers so we don't have to test them in the rest of the library. - * (The terminfo compiler bypasses this logic, since it must know if - * a string is cancelled, for merging entries). - */ - if (status == TGETENT_YES) { - unsigned n; - for_each_boolean(n, tp) { - if (!VALID_BOOLEAN(tp->Booleans[n])) - tp->Booleans[n] = FALSE; - } - for_each_string(n, tp) { - if (tp->Strings[n] == CANCELLED_STRING) - tp->Strings[n] = ABSENT_STRING; - } - } - return (status); -} -#endif - static bool drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) { @@ -168,7 +120,7 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) TCB->magic = TCBMAGIC; #if (USE_DATABASE || USE_TERMCAP) - status = grab_entry(tname, &termp->type); + status = _nc_setup_tinfo(tname, &termp->type); #else status = TGETENT_NO; #endif @@ -188,7 +140,7 @@ 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_error(status, "'%s': unknown terminal type.\n", tname); + ret_error1(status, "unknown terminal type.\n", tname); } } result = TRUE; @@ -201,10 +153,20 @@ drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *errret) _nc_tinfo_cmdch(termp, *command_character); if (generic_type) { - ret_error(TGETENT_NO, "'%s': I need something more specific.\n", tname); + /* + * BSD 4.3's termcap contains mis-typed "gn" for wy99. Do a sanity + * check before giving up. + */ + 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); + } else { + ret_error1(TGETENT_NO, "I need something more specific.\n", tname); + } } if (hard_copy) { - ret_error(TGETENT_YES, "'%s': I can't handle hardcopy terminals.\n", tname); + ret_error1(TGETENT_YES, "I can't handle hardcopy terminals.\n", tname); } return result; @@ -392,25 +354,14 @@ drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *linep, int *colp) /* figure out the size of the screen */ T(("screen size: terminfo lines = %d columns = %d", lines, columns)); - if (!useEnv) { - *linep = (int) lines; - *colp = (int) columns; - } else { /* usually want to query LINES and COLUMNS from environment */ - int value; + *linep = (int) lines; + *colp = (int) columns; - *linep = *colp = 0; - - /* first, look for environment variables */ - if ((value = _nc_getenv_num("LINES")) > 0) { - *linep = value; - } - if ((value = _nc_getenv_num("COLUMNS")) > 0) { - *colp = value; - } - T(("screen size: environment LINES = %d COLUMNS = %d", *linep, *colp)); + if (useEnv) { + int value; #ifdef __EMX__ - if (*linep <= 0 || *colp <= 0) { + { int screendata[2]; _scrsize(screendata); *colp = screendata[0]; @@ -420,34 +371,44 @@ drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *linep, int *colp) } #endif #if HAVE_SIZECHANGE - /* if that didn't work, maybe we can try asking the OS */ - if (*linep <= 0 || *colp <= 0) { + /* try asking the OS */ + { TERMINAL *termp = (TERMINAL *) TCB; if (isatty(termp->Filedes)) { STRUCT_WINSIZE size; errno = 0; do { - if (ioctl(termp->Filedes, IOCTL_WINSIZE, &size) < 0 - && errno != EINTR) - goto failure; + if (ioctl(termp->Filedes, IOCTL_WINSIZE, &size) >= 0) { + *linep = ((sp != 0 && sp->_filtered) + ? 1 + : WINSIZE_ROWS(size)); + *colp = WINSIZE_COLS(size); + T(("SYS screen size: environment LINES = %d COLUMNS = %d", + *linep, *colp)); + break; + } } while (errno == EINTR); - - /* - * Solaris lets users override either dimension with an - * environment variable. - */ - if (*linep <= 0) - *linep = (sp != 0 && sp->_filtered) ? 1 : WINSIZE_ROWS(size); - if (*colp <= 0) - *colp = WINSIZE_COLS(size); } - /* FALLTHRU */ - failure:; } #endif /* HAVE_SIZECHANGE */ + /* + * Finally, look for environment variables. + * + * Solaris lets users override either dimension with an environment + * variable. + */ + if ((value = _nc_getenv_num("LINES")) > 0) { + *linep = value; + T(("screen size: environment LINES = %d", *linep)); + } + if ((value = _nc_getenv_num("COLUMNS")) > 0) { + *colp = value; + T(("screen size: environment COLUMNS = %d", *colp)); + } + /* if we can't get dynamic info about the size, use static */ if (*linep <= 0) { *linep = (int) lines; @@ -548,9 +509,9 @@ drv_mode(TERMINAL_CONTROL_BLOCK * TCB, bool progFlag, bool defFlag) */ if ((drv_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) { #ifdef TERMIOS - _term->Nttyb.c_oflag &= ~OFLAGS_TABS; + _term->Nttyb.c_oflag &= (unsigned) ~OFLAGS_TABS; #else - _term->Nttyb.sg_flags &= ~XTABS; + _term->Nttyb.sg_flags &= (unsigned) ~XTABS; #endif code = OK; } @@ -877,6 +838,39 @@ drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB) } } +static int +drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay) +{ + int rc = 0; + SCREEN *sp; + + AssertTCB(); + SetSP(); + +#if USE_SYSMOUSE + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail)) { + rc = TW_MOUSE; + } else +#endif + { + rc = TCBOf(sp)->drv->twait(TCBOf(sp), + TWAIT_MASK, + delay, + (int *) 0 + EVENTLIST_2nd(evl)); +#if USE_SYSMOUSE + if ((sp->_mouse_type == M_SYSMOUSE) + && (sp->_sysmouse_head < sp->_sysmouse_tail) + && (rc == 0) + && (errno == EINTR)) { + rc |= TW_MOUSE; + } +#endif + } + return rc; +} + static int drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB, int yold, int xold, int ynew, int xnew) { @@ -1172,7 +1166,14 @@ drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf) assert(buf); SetSP(); +# if USE_PTHREADS_EINTR + if ((pthread_self) && (pthread_kill) && (pthread_equal)) + _nc_globals.read_thread = pthread_self(); +# endif n = read(sp->_ifd, &c2, 1); +#if USE_PTHREADS_EINTR + _nc_globals.read_thread = 0; +#endif *buf = (int) c2; return n; } @@ -1309,6 +1310,7 @@ NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_TINFO_DRIVER = { drv_initcolor, /* initcolor */ drv_do_color, /* docolor */ drv_initmouse, /* initmouse */ + drv_testmouse, /* testmouse */ drv_setfilter, /* setfilter */ drv_hwlabel, /* hwlabel */ drv_hwlabelOnOff, /* hwlabelOnOff */