]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/tinfo/lib_setup.c
ncurses 5.1
[ncurses.git] / ncurses / tinfo / lib_setup.c
index 64aa73fa8cf3a2b6177f94712b1a893a3db28d82..50c330eb5739a1e030d98feff067d0760e76dd65 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 1998 Free Software Foundation, Inc.                        *
+ * Copyright (c) 1998,1999,2000 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            *
@@ -31,7 +31,6 @@
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  ****************************************************************************/
 
-
 /*
  * Terminal setup routines common to termcap and terminfo:
  *
  */
 
 #include <curses.priv.h>
-#include <tic.h>       /* for MAX_NAME_SIZE */
+#include <tic.h>               /* for MAX_NAME_SIZE */
 #include <term_entry.h>
 
 #if defined(SVR4_TERMIO) && !defined(_POSIX_SOURCE)
 #define _POSIX_SOURCE
 #endif
 
-#include <term.h>      /* lines, columns, cur_term */
+#include <term.h>              /* lines, columns, cur_term */
 
-MODULE_ID("$Id: lib_setup.c,v 1.55 1999/08/21 23:06:08 tom Exp $")
+MODULE_ID("$Id: lib_setup.c,v 1.59 2000/02/13 01:01:26 tom Exp $")
 
 /****************************************************************************
  *
@@ -95,120 +94,116 @@ static int _use_env = TRUE;
 
 static void do_prototype(void);
 
-void use_env(bool f)
+void
+use_env(bool f)
 {
-       _use_env = f;
+    _use_env = f;
 }
 
-int LINES, COLS, TABSIZE;
+int LINES = 0, COLS = 0, TABSIZE = 0;
 
-static void _nc_get_screensize(int *linep, int *colp)
+static void
+_nc_get_screensize(int *linep, int *colp)
 /* Obtain lines/columns values from the environment and/or terminfo entry */
 {
-       /* figure out the size of the screen */
-       T(("screen size: terminfo lines = %d columns = %d", lines, columns));
+    /* figure out the size of the screen */
+    T(("screen size: terminfo lines = %d columns = %d", lines, columns));
 
-       if (!_use_env)
-       {
-           *linep = (int)lines;
-           *colp  = (int)columns;
-       }
-       else    /* usually want to query LINES and COLUMNS from environment */
-       {
-           int value;
+    if (!_use_env) {
+       *linep = (int) lines;
+       *colp = (int) columns;
+    } else {                   /* usually want to query LINES and COLUMNS from environment */
+       int value;
 
-           *linep = *colp = 0;
+       *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));
+       /* 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));
 
 #ifdef __EMX__
-           if (*linep <= 0 || *colp <= 0)
-           {
-               int screendata[2];
-               _scrsize(screendata);
-               *colp  = screendata[0];
-               *linep = screendata[1];
-               T(("EMX screen size: environment LINES = %d COLUMNS = %d",*linep,*colp));
-           }
+       if (*linep <= 0 || *colp <= 0) {
+           int screendata[2];
+           _scrsize(screendata);
+           *colp = screendata[0];
+           *linep = screendata[1];
+           T(("EMX screen size: environment LINES = %d COLUMNS = %d",
+                   *linep, *colp));
+       }
 #endif
 #if HAVE_SIZECHANGE
-           /* if that didn't work, maybe we can try asking the OS */
-           if (*linep <= 0 || *colp <= 0)
-           {
-               if (isatty(cur_term->Filedes))
-               {
-                   STRUCT_WINSIZE size;
-
-                   errno = 0;
-                   do {
-                       if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) < 0
-                               && errno != EINTR)
-                           goto failure;
-                   } while
-                       (errno == EINTR);
-
-                   /*
-                    * Solaris lets users override either dimension with an
-                    * environment variable.
-                    */
-                   if (*linep <= 0)
-                       *linep = WINSIZE_ROWS(size);
-                   if (*colp <= 0)
-                       *colp  = WINSIZE_COLS(size);
-               }
-               /* FALLTHRU */
-           failure:;
+       /* if that didn't work, maybe we can try asking the OS */
+       if (*linep <= 0 || *colp <= 0) {
+           if (isatty(cur_term->Filedes)) {
+               STRUCT_WINSIZE size;
+
+               errno = 0;
+               do {
+                   if (ioctl(cur_term->Filedes, IOCTL_WINSIZE, &size) < 0
+                       && errno != EINTR)
+                       goto failure;
+               } while
+                   (errno == EINTR);
+
+               /*
+                * Solaris lets users override either dimension with an
+                * environment variable.
+                */
+               if (*linep <= 0)
+                   *linep = WINSIZE_ROWS(size);
+               if (*colp <= 0)
+                   *colp = WINSIZE_COLS(size);
            }
+           /* FALLTHRU */
+         failure:;
+       }
 #endif /* HAVE_SIZECHANGE */
 
-           /* if we can't get dynamic info about the size, use static */
-           if (*linep <= 0 || *colp <= 0)
-               if (lines > 0 && columns > 0)
-               {
-                   *linep = (int)lines;
-                   *colp  = (int)columns;
-               }
-
-           /* the ultimate fallback, assume fixed 24x80 size */
-           if (*linep <= 0 || *colp <= 0)
-           {
-               *linep = 24;
-               *colp  = 80;
+       /* if we can't get dynamic info about the size, use static */
+       if (*linep <= 0 || *colp <= 0)
+           if (lines > 0 && columns > 0) {
+               *linep = (int) lines;
+               *colp = (int) columns;
            }
 
-           /*
-            * Put the derived values back in the screen-size caps, so
-            * tigetnum() and tgetnum() will do the right thing.
-            */
-           lines   = (short)(*linep);
-           columns = (short)(*colp);
+       /* the ultimate fallback, assume fixed 24x80 size */
+       if (*linep <= 0 || *colp <= 0) {
+           *linep = 24;
+           *colp = 80;
        }
 
-       T(("screen size is %dx%d", *linep, *colp));
+       /*
+        * Put the derived values back in the screen-size caps, so
+        * tigetnum() and tgetnum() will do the right thing.
+        */
+       lines = (short) (*linep);
+       columns = (short) (*colp);
+    }
+
+    T(("screen size is %dx%d", *linep, *colp));
 
-       if (init_tabs != -1)
-               TABSIZE = (int)init_tabs;
-       else
-               TABSIZE = 8;
-       T(("TABSIZE = %d", TABSIZE));
+    if (VALID_NUMERIC(init_tabs))
+       TABSIZE = (int) init_tabs;
+    else
+       TABSIZE = 8;
+    T(("TABSIZE = %d", TABSIZE));
 
 }
 
 #if USE_SIZECHANGE
-void _nc_update_screensize(void)
+void
+_nc_update_screensize(void)
 {
-       int my_lines, my_cols;
+    int my_lines, my_cols;
 
-       _nc_get_screensize(&my_lines, &my_cols);
-       if (SP != 0 && SP->_resize != 0)
-               SP->_resize(my_lines, my_cols);
+    _nc_get_screensize(&my_lines, &my_cols);
+    if (SP != 0 && SP->_resize != 0)
+       SP->_resize(my_lines, my_cols);
 }
 #endif
 
@@ -235,52 +230,53 @@ void _nc_update_screensize(void)
                                        }
 
 #if USE_DATABASE
-static int grab_entry(const char *const tn, TERMTYPE *const tp)
+static int
+grab_entry(const char *const tn, TERMTYPE * const tp)
 /* return 1 if entry found, 0 if not found, -1 if database not accessible */
 {
-       char    filename[PATH_MAX];
-       int     status;
+    char filename[PATH_MAX];
+    int status;
 
-       /*
-        * $TERM shouldn't contain pathname delimiters.
-        */
-       if (strchr(tn, '/'))
-               return 0;
+    /*
+     * $TERM shouldn't contain pathname delimiters.
+     */
+    if (strchr(tn, '/'))
+       return 0;
 
-       if ((status = _nc_read_entry(tn, filename, tp)) != 1) {
+    if ((status = _nc_read_entry(tn, filename, tp)) != 1) {
 
 #ifndef PURE_TERMINFO
-               /*
-                * Try falling back on the termcap file.
-                * Note:  allowing this call links the entire terminfo/termcap
-                * compiler into the startup code.  It's preferable to build a
-                * real terminfo database and use that.
-                */
-               status = _nc_read_termcap_entry(tn, tp);
-#endif /* PURE_TERMINFO */
-
-       }
-
        /*
-        * 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).
+        * Try falling back on the termcap file.
+        * Note:  allowing this call links the entire terminfo/termcap
+        * compiler into the startup code.  It's preferable to build a
+        * real terminfo database and use that.
         */
-       if (status == 1) {
-               int 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);
+       status = _nc_read_termcap_entry(tn, tp);
+#endif /* PURE_TERMINFO */
+
+    }
+
+    /*
+     * 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 == 1) {
+       int 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
 
-char ttytype[NAMESIZE];
+char ttytype[NAMESIZE] = "";
 
 /*
  *     setupterm(termname, Filedes, errret)
@@ -290,107 +286,103 @@ char ttytype[NAMESIZE];
  *
  */
 
-int setupterm(NCURSES_CONST char *tname, int Filedes, int *errret)
+int
+setupterm(NCURSES_CONST char *tname, int Filedes, int *errret)
 {
-struct term    *term_ptr;
-int status;
+    struct term *term_ptr;
+    int status;
 
-       T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret));
+    T((T_CALLED("setupterm(%s,%d,%p)"), _nc_visbuf(tname), Filedes, errret));
 
-       if (tname == 0) {
-               tname = getenv("TERM");
-               if (tname == 0 || *tname == '\0') {
-                       ret_error0(-1, "TERM environment variable not set.\n");
-                }
-       }
-       if (strlen(tname) > MAX_NAME_SIZE) {
-               ret_error(-1, "TERM environment must be <= %d characters.\n",
-                   MAX_NAME_SIZE);
+    if (tname == 0) {
+       tname = getenv("TERM");
+       if (tname == 0 || *tname == '\0') {
+           ret_error0(-1, "TERM environment variable not set.\n");
        }
+    }
+    if (strlen(tname) > MAX_NAME_SIZE) {
+       ret_error(-1, "TERM environment must be <= %d characters.\n",
+           MAX_NAME_SIZE);
+    }
 
-       T(("your terminal name is %s", tname));
+    T(("your terminal name is %s", tname));
 
-       term_ptr = typeCalloc(TERMINAL, 1);
+    term_ptr = typeCalloc(TERMINAL, 1);
 
-       if (term_ptr == 0) {
-               ret_error0(-1, "Not enough memory to create terminal structure.\n") ;
-        }
+    if (term_ptr == 0) {
+       ret_error0(-1, "Not enough memory to create terminal structure.\n");
+    }
 #if USE_DATABASE
-       status = grab_entry(tname, &term_ptr->type);
+    status = grab_entry(tname, &term_ptr->type);
 #else
-       status = 0;
+    status = 0;
 #endif
 
-       /* try fallback list if entry on disk */
-       if (status != 1)
-       {
-           const TERMTYPE      *fallback = _nc_fallback(tname);
-
-           if (fallback)
-           {
-               term_ptr->type = *fallback;
-               status = 1;
-           }
-       }
-
-       if (status == -1)
-       {
-               ret_error0(-1, "terminals database is inaccessible\n");
-       }
-       else if (status == 0)
-       {
-               ret_error(0, "'%s': unknown terminal type.\n", tname);
-       }
-
-       /*
-        * Improve on SVr4 curses.  If an application mixes curses and termcap
-        * calls, it may call both initscr and tgetent.  This is not really a
-        * good thing to do, but can happen if someone tries using ncurses with
-        * the readline library.  The problem we are fixing is that when
-        * tgetent calls setupterm, the resulting Ottyb struct in cur_term is
-        * zeroed.  A subsequent call to endwin uses the zeroed terminal
-        * settings rather than the ones saved in initscr.  So we check if
-        * cur_term appears to contain terminal settings for the same output
-        * file as our current call - and copy those terminal settings.  (SVr4
-        * curses does not do this, however applications that are working
-        * around the problem will still work properly with this feature).
-        */
-       if (cur_term != 0) {
-               if (cur_term->Filedes == Filedes)
-                       term_ptr->Ottyb = cur_term->Ottyb;
-       }
-
-       set_curterm(term_ptr);
-
-       if (command_character  &&  getenv("CC"))
-               do_prototype();
-
-       strncpy(ttytype, cur_term->type.term_names, NAMESIZE - 1);
-       ttytype[NAMESIZE - 1] = '\0';
-
-       /*
-        * Allow output redirection.  This is what SVr3 does.
-        * If stdout is directed to a file, screen updates go
-        * to standard error.
-        */
-       if (Filedes == STDOUT_FILENO && !isatty(Filedes))
-           Filedes = STDERR_FILENO;
-       cur_term->Filedes = Filedes;
-
-       _nc_get_screensize(&LINES, &COLS);
-
-       if (errret)
-               *errret = 1;
+    /* try fallback list if entry on disk */
+    if (status != 1) {
+       const TERMTYPE *fallback = _nc_fallback(tname);
 
-       T((T_CREATE("screen %s %dx%d"), tname, LINES, COLS));
-
-       if (generic_type) {
-               ret_error(0, "'%s': I need something more specific.\n", tname);
-       }
-       if (hard_copy) {
-               ret_error(1, "'%s': I can't handle hardcopy terminals.\n", tname);
+       if (fallback) {
+           term_ptr->type = *fallback;
+           status = 1;
        }
-       returnCode(OK);
+    }
+
+    if (status == -1) {
+       ret_error0(-1, "terminals database is inaccessible\n");
+    } else if (status == 0) {
+       ret_error(0, "'%s': unknown terminal type.\n", tname);
+    }
+
+    /*
+     * Improve on SVr4 curses.  If an application mixes curses and termcap
+     * calls, it may call both initscr and tgetent.  This is not really a
+     * good thing to do, but can happen if someone tries using ncurses with
+     * the readline library.  The problem we are fixing is that when
+     * tgetent calls setupterm, the resulting Ottyb struct in cur_term is
+     * zeroed.  A subsequent call to endwin uses the zeroed terminal
+     * settings rather than the ones saved in initscr.  So we check if
+     * cur_term appears to contain terminal settings for the same output
+     * file as our current call - and copy those terminal settings.  (SVr4
+     * curses does not do this, however applications that are working
+     * around the problem will still work properly with this feature).
+     */
+    if (cur_term != 0) {
+       if (cur_term->Filedes == Filedes)
+           term_ptr->Ottyb = cur_term->Ottyb;
+    }
+
+    set_curterm(term_ptr);
+
+    if (command_character && getenv("CC"))
+       do_prototype();
+
+    strncpy(ttytype, cur_term->type.term_names, NAMESIZE - 1);
+    ttytype[NAMESIZE - 1] = '\0';
+
+    /*
+     * Allow output redirection.  This is what SVr3 does.
+     * If stdout is directed to a file, screen updates go
+     * to standard error.
+     */
+    if (Filedes == STDOUT_FILENO && !isatty(Filedes))
+       Filedes = STDERR_FILENO;
+    cur_term->Filedes = Filedes;
+
+    _nc_get_screensize(&LINES, &COLS);
+
+    if (errret)
+       *errret = 1;
+
+    T((T_CREATE("screen %s %dx%d"), tname, LINES, COLS));
+
+    if (generic_type) {
+       ret_error(0, "'%s': I need something more specific.\n", tname);
+    }
+    if (hard_copy) {
+       ret_error(1, "'%s': I can't handle hardcopy terminals.\n", tname);
+    }
+    returnCode(OK);
 }
 
 /*
@@ -404,19 +396,19 @@ int status;
 static void
 do_prototype(void)
 {
-int    i;
-char   CC;
-char   proto;
-char    *tmp;
-
-       tmp = getenv("CC");
-       CC = *tmp;
-       proto = *command_character;
-
-       for_each_string(i, &(cur_term->type)) {
-           for (tmp = cur_term->type.Strings[i]; *tmp; tmp++) {
-               if (*tmp == proto)
-                   *tmp = CC;
-           }
+    int i;
+    char CC;
+    char proto;
+    char *tmp;
+
+    tmp = getenv("CC");
+    CC = *tmp;
+    proto = *command_character;
+
+    for_each_string(i, &(cur_term->type)) {
+       for (tmp = cur_term->type.Strings[i]; *tmp; tmp++) {
+           if (*tmp == proto)
+               *tmp = CC;
        }
+    }
 }