]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - ncurses/tinfo/tinfo_driver.c
ncurses 5.9 - patch 20110507
[ncurses.git] / ncurses / tinfo / tinfo_driver.c
index 22c31594901b2baeb5a974fe72e282626a3fb095..5b3b55a4519e23e789da88fa23d856d17867f177 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * Copyright (c) 2008,2009 Free Software Foundation, Inc.                   *
+ * Copyright (c) 2008-2009,2010 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.5 2009/10/31 20:32:01 tom Exp $")
+MODULE_ID("$Id: tinfo_driver.c,v 1.13 2010/12/20 01:47:09 tom Exp $")
 
 /*
  * SCO defines TIOCGSIZE and the corresponding struct.  Other systems (SunOS,
@@ -91,84 +91,6 @@ NCURSES_EXPORT_VAR(int) COLOR_PAIRS = 0;
 NCURSES_EXPORT_VAR(int) COLORS = 0;
 #endif
 
-static bool drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB, const char *tname, int *);
-static void drv_init(TERMINAL_CONTROL_BLOCK *);
-static void drv_release(TERMINAL_CONTROL_BLOCK *);
-static int drv_size(TERMINAL_CONTROL_BLOCK *, int *, int *);
-static int drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, bool setFlag, TTY * buf);
-static chtype drv_conattr(TERMINAL_CONTROL_BLOCK * TCB);
-static int drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB, int yold, int xold, int
-                    ynew, int xnew);
-static int drv_mode(TERMINAL_CONTROL_BLOCK * TCB, bool progFlag, bool defFlag);
-static bool drv_rescol(TERMINAL_CONTROL_BLOCK * TCB);
-static bool drv_rescolors(TERMINAL_CONTROL_BLOCK * TCB);
-static void drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB, bool fore, int color, int
-                          (*outc) (SCREEN *, int));
-static int drv_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB, bool beepFlag);
-static void drv_initpair(TERMINAL_CONTROL_BLOCK * TCB, short pair, short f, short b);
-static void drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB, short color, short
-                         r, short g, short b);
-static void drv_do_color(TERMINAL_CONTROL_BLOCK * TCB, short old_pair, short
-                        pair, bool reverse,
-                        int (*outc) (SCREEN *, int));
-static void drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB);
-static void drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB);
-static void drv_hwlabel(TERMINAL_CONTROL_BLOCK * TCB, int labnum, char *text);
-static void drv_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB, bool OnFlag);
-static int drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB);
-static int drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB, int fg, int bg);
-static int drv_print(TERMINAL_CONTROL_BLOCK * TCB, char *data, int len);
-static int drv_getsize(TERMINAL_CONTROL_BLOCK *, int *, int *);
-static int drv_setsize(TERMINAL_CONTROL_BLOCK * TCB, int l, int c);
-static void drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *, chtype *);
-static void drv_wrap(SCREEN *);
-static void drv_screen_init(SCREEN *);
-static int drv_twait(TERMINAL_CONTROL_BLOCK *, int, int, int
-                    *EVENTLIST_2nd(_nc_eventlist
-                                   *));
-static int drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf);
-static int drv_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms);
-static int drv_kpad(TERMINAL_CONTROL_BLOCK * TCB, bool);
-static int drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int, bool);
-static bool drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int);
-
-NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_TINFO_DRIVER = {
-    TRUE,
-       drv_CanHandle,          /* CanHandle */
-       drv_init,               /* init */
-       drv_release,            /* release */
-       drv_size,               /* size */
-       drv_sgmode,             /* sgmode */
-       drv_conattr,            /* conattr */
-       drv_mvcur,              /* hwcur */
-       drv_mode,               /* mode */
-       drv_rescol,             /* rescol */
-       drv_rescolors,          /* rescolors */
-       drv_setcolor,           /* color */
-       drv_dobeepflash,        /* doBeepOrFlash */
-       drv_initpair,           /* initpair */
-       drv_initcolor,          /* initcolor */
-       drv_do_color,           /* docolor */
-       drv_initmouse,          /* initmouse */
-       drv_setfilter,          /* setfilter */
-       drv_hwlabel,            /* hwlabel */
-       drv_hwlabelOnOff,       /* hwlabelOnOff */
-       drv_doupdate,           /* update */
-       drv_defaultcolors,      /* defaultcolors */
-       drv_print,              /* print */
-       drv_getsize,            /* getsize */
-       drv_setsize,            /* setsize */
-       drv_initacs,            /* initacs */
-       drv_screen_init,        /* scinit */
-       drv_wrap,               /* scexit */
-       drv_twait,              /* twait  */
-       drv_read,               /* read */
-       drv_nap,                /* nap */
-       drv_kpad,               /* kpad */
-       drv_keyok,              /* kyOk */
-       drv_kyExist             /* kyExist */
-};
-
 #define TCBMAGIC NCDRV_MAGIC(NCDRV_TINFO)
 #define AssertTCB() assert(TCB!=0 && TCB->magic==TCBMAGIC)
 #define SetSP() assert(TCB->csp!=0); sp = TCB->csp
@@ -200,38 +122,6 @@ drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
                                            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)
 {
@@ -246,7 +136,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
@@ -386,8 +276,10 @@ drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB, int fg, int bg)
 }
 
 static void
-drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB, bool fore, int color, int (*outc)
-              (SCREEN *, int))
+drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
+            bool fore,
+            int color,
+            NCURSES_SP_OUTC outc)
 {
     SCREEN *sp;
 
@@ -468,25 +360,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];
@@ -496,34 +377,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;
@@ -566,11 +457,45 @@ static int
 drv_setsize(TERMINAL_CONTROL_BLOCK * TCB, int l, int c)
 {
     AssertTCB();
-    lines = l;
-    columns = c;
+    lines = (short) l;
+    columns = (short) c;
     return OK;
 }
 
+static int
+drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, bool setFlag, TTY * buf)
+{
+    SCREEN *sp = TCB->csp;
+    TERMINAL *_term = (TERMINAL *) TCB;
+    int result = OK;
+
+    AssertTCB();
+    if (setFlag) {
+       for (;;) {
+           if (SET_TTY(_term->Filedes, buf) != 0) {
+               if (errno == EINTR)
+                   continue;
+               if (errno == ENOTTY) {
+                   if (sp)
+                       sp->_notty = TRUE;
+               }
+               result = ERR;
+           }
+           break;
+       }
+    } else {
+       for (;;) {
+           if (GET_TTY(_term->Filedes, buf) != 0) {
+               if (errno == EINTR)
+                   continue;
+               result = ERR;
+           }
+           break;
+       }
+    }
+    return result;
+}
+
 static int
 drv_mode(TERMINAL_CONTROL_BLOCK * TCB, bool progFlag, bool defFlag)
 {
@@ -590,9 +515,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;
            }
@@ -653,7 +578,7 @@ drv_release(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED)
 
 #  define SGR0_TEST(mode) (mode != 0) && (exit_attribute_mode == 0 || strcmp(mode, exit_attribute_mode))
 
-void
+static void
 drv_screen_init(SCREEN *sp)
 {
     TERMINAL_CONTROL_BLOCK *TCB = TCBOf(sp);
@@ -865,9 +790,9 @@ drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
 
 #if NCURSES_EXT_FUNCS
     if (isDefaultColor(fg))
-       fg = default_fg(sp);
+       fg = (NCURSES_COLOR_T) default_fg(sp);
     if (isDefaultColor(bg))
-       bg = default_bg(sp);
+       bg = (NCURSES_COLOR_T) default_bg(sp);
 #endif
 
     if (reverse) {
@@ -919,6 +844,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)
 {
@@ -1006,40 +964,6 @@ drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB)
     cursor_home = carriage_return;
 }
 
-static int
-drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, bool setFlag, TTY * buf)
-{
-    SCREEN *sp = TCB->csp;
-    TERMINAL *_term = (TERMINAL *) TCB;
-    int result = OK;
-
-    AssertTCB();
-    if (setFlag) {
-       for (;;) {
-           if (SET_TTY(_term->Filedes, buf) != 0) {
-               if (errno == EINTR)
-                   continue;
-               if (errno == ENOTTY) {
-                   if (sp)
-                       sp->_notty = TRUE;
-               }
-               result = ERR;
-           }
-           break;
-       }
-    } else {
-       for (;;) {
-           if (GET_TTY(_term->Filedes, buf) != 0) {
-               if (errno == EINTR)
-                   continue;
-               result = ERR;
-           }
-           break;
-       }
-    }
-    return result;
-}
-
 static void
 drv_initacs(TERMINAL_CONTROL_BLOCK * TCB, chtype *real_map, chtype *fake_map)
 {
@@ -1248,7 +1172,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;
 }
@@ -1366,3 +1297,41 @@ drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int key)
 
     return res;
 }
+
+NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_TINFO_DRIVER = {
+    TRUE,
+       drv_CanHandle,          /* CanHandle */
+       drv_init,               /* init */
+       drv_release,            /* release */
+       drv_size,               /* size */
+       drv_sgmode,             /* sgmode */
+       drv_conattr,            /* conattr */
+       drv_mvcur,              /* hwcur */
+       drv_mode,               /* mode */
+       drv_rescol,             /* rescol */
+       drv_rescolors,          /* rescolors */
+       drv_setcolor,           /* color */
+       drv_dobeepflash,        /* doBeepOrFlash */
+       drv_initpair,           /* initpair */
+       drv_initcolor,          /* initcolor */
+       drv_do_color,           /* docolor */
+       drv_initmouse,          /* initmouse */
+       drv_testmouse,          /* testmouse */
+       drv_setfilter,          /* setfilter */
+       drv_hwlabel,            /* hwlabel */
+       drv_hwlabelOnOff,       /* hwlabelOnOff */
+       drv_doupdate,           /* update */
+       drv_defaultcolors,      /* defaultcolors */
+       drv_print,              /* print */
+       drv_getsize,            /* getsize */
+       drv_setsize,            /* setsize */
+       drv_initacs,            /* initacs */
+       drv_screen_init,        /* scinit */
+       drv_wrap,               /* scexit */
+       drv_twait,              /* twait  */
+       drv_read,               /* read */
+       drv_nap,                /* nap */
+       drv_kpad,               /* kpad */
+       drv_keyok,              /* kyOk */
+       drv_kyExist             /* kyExist */
+};