ncurses 5.7 - patch 20091219
[ncurses.git] / ncurses / tinfo / lib_acs.c
index ba35ab70b0bd5d6e49d12726de3c87fb63118866..5be3659f021f2f8f4728ed148fa01e5296a10ee9 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
 /****************************************************************************
- * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
+ * Copyright (c) 1998-2008,2009 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            *
  *                                                                          *
  * Permission is hereby granted, free of charge, to any person obtaining a  *
  * copy of this software and associated documentation files (the            *
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
 /****************************************************************************
  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ *     and: Thomas E. Dickey                        1996-on                 *
+ *     and: Juergen Pfeifer                         2008                    *
  ****************************************************************************/
 
 #include <curses.priv.h>
  ****************************************************************************/
 
 #include <curses.priv.h>
-#include <term.h>              /* ena_acs, acs_chars */
 
 
-MODULE_ID("$Id: lib_acs.c,v 1.22 2002/09/01 19:26:57 tom Exp $")
+#ifndef CUR
+#define CUR SP_TERMTYPE
+#endif
+
+MODULE_ID("$Id: lib_acs.c,v 1.41 2009/10/04 00:26:54 tom Exp $")
 
 
-#if BROKEN_LINKER
-NCURSES_EXPORT_VAR(chtype *)
-_nc_acs_map(void)
+#if BROKEN_LINKER || USE_REENTRANT
+#define MyBuffer _nc_prescreen.real_acs_map
+NCURSES_EXPORT(chtype *)
+NCURSES_PUBLIC_VAR(acs_map) (void)
 {
 {
-    static chtype *the_map = 0;
-    if (the_map == 0)
-       the_map = typeCalloc(chtype, ACS_LEN);
-    return the_map;
+    if (MyBuffer == 0)
+       MyBuffer = typeCalloc(chtype, ACS_LEN);
+    return MyBuffer;
 }
 }
+#undef MyBuffer
 #else
 #else
-NCURSES_EXPORT_VAR(chtype) acs_map[ACS_LEN] =
+NCURSES_EXPORT_VAR (chtype) acs_map[ACS_LEN] =
 {
     0
 };
 #endif
 
 {
     0
 };
 #endif
 
+#ifdef USE_TERM_DRIVER
+NCURSES_EXPORT(chtype)
+NCURSES_SP_NAME(_nc_acs_char) (NCURSES_SP_DCLx int c)
+{
+    chtype *map;
+    if (c < 0 || c >= ACS_LEN)
+       return (chtype) 0;
+    map = (SP_PARM != 0) ? SP_PARM->_acs_map :
+#if BROKEN_LINKER || USE_REENTRANT
+       _nc_prescreen.real_acs_map
+#else
+       acs_map
+#endif
+       ;
+    return map[c];
+}
+#endif /* USE_TERM_DRIVER */
+
 NCURSES_EXPORT(void)
 NCURSES_EXPORT(void)
-_nc_init_acs(void)
+NCURSES_SP_NAME(_nc_init_acs) (NCURSES_SP_DCL0)
 {
 {
+    chtype *fake_map = acs_map;
+    chtype *real_map = SP_PARM != 0 ? SP_PARM->_acs_map : fake_map;
+    int j;
+
     T(("initializing ACS map"));
     T(("initializing ACS map"));
-#if !BROKEN_LINKER
-    memset(acs_map, 0, sizeof(acs_map));
-#endif
+
+    /*
+     * If we're using this from curses (rather than terminfo), we are storing
+     * the mapping information in the SCREEN struct so we can decide how to
+     * render it.
+     */
+    if (real_map != fake_map) {
+       for (j = 1; j < ACS_LEN; ++j) {
+           real_map[j] = 0;
+           fake_map[j] = A_ALTCHARSET | j;
+           if (SP_PARM)
+               SP_PARM->_screen_acs_map[j] = FALSE;
+       }
+    } else {
+       for (j = 1; j < ACS_LEN; ++j) {
+           real_map[j] = 0;
+       }
+    }
 
     /*
      * Initializations for a UNIX-like multi-terminal environment.  Use
      * ASCII chars and count on the terminfo description to do better.
      */
 
     /*
      * Initializations for a UNIX-like multi-terminal environment.  Use
      * ASCII chars and count on the terminfo description to do better.
      */
-    ACS_ULCORNER = '+';                /* should be upper left corner */
-    ACS_LLCORNER = '+';                /* should be lower left corner */
-    ACS_URCORNER = '+';                /* should be upper right corner */
-    ACS_LRCORNER = '+';                /* should be lower right corner */
-    ACS_RTEE = '+';            /* should be tee pointing left */
-    ACS_LTEE = '+';            /* should be tee pointing right */
-    ACS_BTEE = '+';            /* should be tee pointing up */
-    ACS_TTEE = '+';            /* should be tee pointing down */
-    ACS_HLINE = '-';           /* should be horizontal line */
-    ACS_VLINE = '|';           /* should be vertical line */
-    ACS_PLUS = '+';            /* should be large plus or crossover */
-    ACS_S1 = '~';              /* should be scan line 1 */
-    ACS_S9 = '_';              /* should be scan line 9 */
-    ACS_DIAMOND = '+';         /* should be diamond */
-    ACS_CKBOARD = ':';         /* should be checker board (stipple) */
-    ACS_DEGREE = '\'';         /* should be degree symbol */
-    ACS_PLMINUS = '#';         /* should be plus/minus */
-    ACS_BULLET = 'o';          /* should be bullet */
-    ACS_LARROW = '<';          /* should be arrow pointing left */
-    ACS_RARROW = '>';          /* should be arrow pointing right */
-    ACS_DARROW = 'v';          /* should be arrow pointing down */
-    ACS_UARROW = '^';          /* should be arrow pointing up */
-    ACS_BOARD = '#';           /* should be board of squares */
-    ACS_LANTERN = '#';         /* should be lantern symbol */
-    ACS_BLOCK = '#';           /* should be solid square block */
+    real_map['l'] = '+';       /* should be upper left corner */
+    real_map['m'] = '+';       /* should be lower left corner */
+    real_map['k'] = '+';       /* should be upper right corner */
+    real_map['j'] = '+';       /* should be lower right corner */
+    real_map['u'] = '+';       /* should be tee pointing left */
+    real_map['t'] = '+';       /* should be tee pointing right */
+    real_map['v'] = '+';       /* should be tee pointing up */
+    real_map['w'] = '+';       /* should be tee pointing down */
+    real_map['q'] = '-';       /* should be horizontal line */
+    real_map['x'] = '|';       /* should be vertical line */
+    real_map['n'] = '+';       /* should be large plus or crossover */
+    real_map['o'] = '~';       /* should be scan line 1 */
+    real_map['s'] = '_';       /* should be scan line 9 */
+    real_map['`'] = '+';       /* should be diamond */
+    real_map['a'] = ':';       /* should be checker board (stipple) */
+    real_map['f'] = '\'';      /* should be degree symbol */
+    real_map['g'] = '#';       /* should be plus/minus */
+    real_map['~'] = 'o';       /* should be bullet */
+    real_map[','] = '<';       /* should be arrow pointing left */
+    real_map['+'] = '>';       /* should be arrow pointing right */
+    real_map['.'] = 'v';       /* should be arrow pointing down */
+    real_map['-'] = '^';       /* should be arrow pointing up */
+    real_map['h'] = '#';       /* should be board of squares */
+    real_map['i'] = '#';       /* should be lantern symbol */
+    real_map['0'] = '#';       /* should be solid square block */
     /* these defaults were invented for ncurses */
     /* these defaults were invented for ncurses */
-    ACS_S3 = '-';              /* should be scan line 3 */
-    ACS_S7 = '-';              /* should be scan line 7 */
-    ACS_LEQUAL = '<';          /* should be less-than-or-equal-to */
-    ACS_GEQUAL = '>';          /* should be greater-than-or-equal-to */
-    ACS_PI = '*';              /* should be greek pi */
-    ACS_NEQUAL = '!';          /* should be not-equal */
-    ACS_STERLING = 'f';                /* should be pound-sterling symbol */
+    real_map['p'] = '-';       /* should be scan line 3 */
+    real_map['r'] = '-';       /* should be scan line 7 */
+    real_map['y'] = '<';       /* should be less-than-or-equal-to */
+    real_map['z'] = '>';       /* should be greater-than-or-equal-to */
+    real_map['{'] = '*';       /* should be greek pi */
+    real_map['|'] = '!';       /* should be not-equal */
+    real_map['}'] = 'f';       /* should be pound-sterling symbol */
+    /* thick-line-drawing */
+    real_map['L'] = '+';       /* upper left corner */
+    real_map['M'] = '+';       /* lower left corner */
+    real_map['K'] = '+';       /* upper right corner */
+    real_map['J'] = '+';       /* lower right corner */
+    real_map['T'] = '+';       /* tee pointing left */
+    real_map['U'] = '+';       /* tee pointing right */
+    real_map['V'] = '+';       /* tee pointing up */
+    real_map['W'] = '+';       /* tee pointing down */
+    real_map['Q'] = '-';       /* horizontal line */
+    real_map['X'] = '|';       /* vertical line */
+    real_map['N'] = '+';       /* large plus or crossover */
+    /* double-line-drawing */
+    real_map['C'] = '+';       /* upper left corner */
+    real_map['D'] = '+';       /* lower left corner */
+    real_map['B'] = '+';       /* upper right corner */
+    real_map['A'] = '+';       /* lower right corner */
+    real_map['G'] = '+';       /* tee pointing left */
+    real_map['F'] = '+';       /* tee pointing right */
+    real_map['H'] = '+';       /* tee pointing up */
+    real_map['I'] = '+';       /* tee pointing down */
+    real_map['R'] = '-';       /* horizontal line */
+    real_map['Y'] = '|';       /* vertical line */
+    real_map['E'] = '+';       /* large plus or crossover */
 
 
+#ifdef USE_TERM_DRIVER
+    CallDriver_2(SP_PARM, initacs, real_map, fake_map);
+#else
     if (ena_acs != NULL) {
        TPUTS_TRACE("ena_acs");
        putp(ena_acs);
     }
     if (ena_acs != NULL) {
        TPUTS_TRACE("ena_acs");
        putp(ena_acs);
     }
-#define ALTCHAR(c)     ((chtype)(((unsigned char)(c)) | A_ALTCHARSET))
+#if NCURSES_EXT_FUNCS
+    /*
+     * Linux console "supports" the "PC ROM" character set by the coincidence
+     * that smpch/rmpch and smacs/rmacs have the same values.  ncurses has
+     * no codepage support (see SCO Merge for an example).  Outside of the
+     * values defined in acsc, there are no definitions for the "PC ROM"
+     * character set (assumed by some applications to be codepage 437), but we
+     * allow those applications to use those codepoints.
+     *
+     * test/blue.c uses this feature.
+     */
+#define PCH_KLUDGE(a,b) (a != 0 && b != 0 && !strcmp(a,b))
+    if (PCH_KLUDGE(enter_pc_charset_mode, enter_alt_charset_mode) &&
+       PCH_KLUDGE(exit_pc_charset_mode, exit_alt_charset_mode)) {
+       size_t i;
+       for (i = 1; i < ACS_LEN; ++i) {
+           if (real_map[i] == 0) {
+               real_map[i] = i;
+               if (real_map != fake_map) {
+                   if (SP != 0)
+                       SP->_screen_acs_map[i] = TRUE;
+               }
+           }
+       }
+    }
+#endif
 
     if (acs_chars != NULL) {
        size_t i = 0;
        size_t length = strlen(acs_chars);
 
 
     if (acs_chars != NULL) {
        size_t i = 0;
        size_t length = strlen(acs_chars);
 
-       while (i < length)
-           switch (acs_chars[i]) {
-           case 'l':
-           case 'm':
-           case 'k':
-           case 'j':
-           case 'u':
-           case 't':
-           case 'v':
-           case 'w':
-           case 'q':
-           case 'x':
-           case 'n':
-           case 'o':
-           case 's':
-           case '`':
-           case 'a':
-           case 'f':
-           case 'g':
-           case '~':
-           case ',':
-           case '+':
-           case '.':
-           case '-':
-           case 'h':
-           case 'i':
-           case '0':
-           case 'p':
-           case 'r':
-           case 'y':
-           case 'z':
-           case '{':
-           case '|':
-           case '}':
-               acs_map[(unsigned int) acs_chars[i]] =
-                   ALTCHAR(acs_chars[i + 1]);
-               i++;
-               /* FALLTHRU */
-           default:
-               i++;
-               break;
+       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)
+                   SP->_screen_acs_map[UChar(acs_chars[i])] = TRUE;
            }
            }
+           i += 2;
+       }
     }
 #ifdef TRACE
     /* Show the equivalent mapping, noting if it does not match the
      * given attribute, whether by re-ordering or duplication.
      */
     }
 #ifdef TRACE
     /* Show the equivalent mapping, noting if it does not match the
      * given attribute, whether by re-ordering or duplication.
      */
-    if (_nc_tracing & TRACE_CALLS) {
+    if (USE_TRACEF(TRACE_CALLS)) {
        size_t n, m;
        size_t n, m;
-       char show[ACS_LEN + 1];
+       char show[ACS_LEN * 2 + 1];
        for (n = 1, m = 0; n < ACS_LEN; n++) {
        for (n = 1, m = 0; n < ACS_LEN; n++) {
-           if (acs_map[n] != 0) {
+           if (real_map[n] != 0) {
                show[m++] = (char) n;
                show[m++] = (char) n;
-               show[m++] = ChCharOf(acs_map[n]);
+               show[m++] = (char) ChCharOf(real_map[n]);
            }
        }
        show[m] = 0;
            }
        }
        show[m] = 0;
+       if (acs_chars == NULL || strcmp(acs_chars, show))
+           _tracef("%s acs_chars %s",
+                   (acs_chars == NULL) ? "NULL" : "READ",
+                   _nc_visbuf(acs_chars));
        _tracef("%s acs_chars %s",
                (acs_chars == NULL)
                ? "NULL"
        _tracef("%s acs_chars %s",
                (acs_chars == NULL)
                ? "NULL"
@@ -172,6 +237,16 @@ _nc_init_acs(void)
                   ? "DIFF"
                   : "SAME"),
                _nc_visbuf(show));
                   ? "DIFF"
                   : "SAME"),
                _nc_visbuf(show));
+       _nc_unlock_global(tracef);
     }
 #endif /* TRACE */
     }
 #endif /* TRACE */
+#endif
 }
 }
+
+#if NCURSES_SP_FUNCS
+NCURSES_EXPORT(void)
+_nc_init_acs(void)
+{
+    NCURSES_SP_NAME(_nc_init_acs) (CURRENT_SCREEN);
+}
+#endif