bug-texinfo
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

MS-Windows build of Texinfo


From: Eli Zaretskii
Subject: MS-Windows build of Texinfo
Date: Tue, 17 Jan 2012 08:41:10 +0200

It always annoyed me that the Info reader doesn't work on MS-Windows,
because no one wrote the code for screen output and keyboard input for
that platform.  So I finally did it myself.

The set of patches below are mainly for this issue, but they also
solve a compiler warning in building makeinfo and fix a crash in man.c
for !PIPE_USE_FORK platforms.

Let me know if something here is unclear or needs more changes.

Thanks.

2012-01-17  Eli Zaretskii  <address@hidden>

        Support for MS-Windows screen and keyboard in Info.

        * system.h (SET_SCREEN_SIZE_HELPER) [__MINGW32__]: Define.

        * info/tilde.c (tilde_expand_word) [__MINGW32__]: Don't call
        getpwuid or getpwnam; instead, consider "." as "home" if HOME is
        not set in the environment.  Support tilde_expansion_failure_hook.

        * info/terminal.c [_WIN32]: Include pcterm.h.
        (terminal_initialize_terminal) [__MINGW32__]: Don't access
        `ospeed'.
        (terminal_prep_terminal, terminal_unprep_terminal) [__MINGW32__]:
        Ifdef away the TIOC code for Windows.

        * info/termdep.h [__MINGW32__]: Don't include sgtty.h.
        [_WIN32]: Add a prototype for `sleep'.

        * info/signals.c (redisplay_after_signal)
        (reset_info_window_sizes): Make these 2 functions extern from
        static, as they are called on MS-Windows from other files.

        * info/session.c (read) [__MINGW32__]: Redirect read and _read to
        w32_read.
        (info_gather_typeahead) [__MINGW32__]: Call w32_chars_avail to
        find out how many typeahead is available.

        * info/pcterm.c <struct text_info, struct termios> [_WIN32]:
        Definitions for the MS-Windows build.
        (w32_info_prep, w32_info_unprep, w32_cleanup, w32_info_init)
        (gettextinfo, textattr, textmode, ScreenGetCursor)
        (ScreenSetCursor, ScreenClear, clreol, ScreenVisualBell)
        (movetext, ScreenRows, ScreenCols, _set_screen_lines)
        (w32_set_screen_dimensions) [_WIN32]: New; screen output and
        cursor control functions for MS-Windows.
        (sleep, w32_our_tty, define_seq, w32keyseq, w32_kbd_read)
        (w32_chars_avail, w32_read) [_WIN32]: New; keyboard input
        functions and their subroutines for MS-Windows.
        (pc_prep_terminal) [_WIN32]: Call w32_info_prep.
        (pc_unprep_terminal) [_WIN32]: Call w32_info_unprep.  Restore the
        screen buffer size to what we found on startup.
        (pc_initialize_terminal) [_WIN32]: Let term_name be "w32console".
        Condition MSDOS key definitions on __MSDOS__.
        (kill) [_WIN32]: Don't clear the screen and don't write "stopped"
        message on MS-Windows.  Special suspend code for MS-Windows.

        * info/man.c [__MINGW32__]: Don't include sys/ioctl.h.

        Fix a crash in vewing man pages.

        * info/man.c (get_manpage_contents) [!PIPE_USE_FORK]: Fix a
        crasher due to addition of "-a" to the man command line arguments.

        Miscellaneous MS-Windows related fixes.

        * info/infokey.c (main): On MS-Windows, consider the current
        directory a "home" if HOME is not defined in the environment.

        * info/infomap.c (fetch_user_maps): Likewise.

        * info/info.c <option long_options>: Enable the speech-friendly
        options on MS-Windows as well.
        (main): Likewise.

        * info/dir.c (new_dir_file_p): Don't optimize the test for a new
        file when the inode is zero (MS-Windows).

        * makeinfo/index.c: Add a prototype for mbscasecmp.

diff -ubBwp -r texinfo-4.13.orig/system.h texinfo-4.13/system.h
--- texinfo-4.13.orig/system.h  2008-07-27 02:54:54.000000000 +0300
+++ texinfo-4.13/system.h       2011-08-10 09:10:17.212615400 +0300
@@ -184,6 +184,9 @@ extern int strcoll ();
 #  define NULL_DEVICE "/dev/null"
 #  define PIPE_USE_FORK        1
 # else  /* O_BINARY && !__CYGWIN__ */
+#  ifdef __MINGW32__
+#   define SET_SCREEN_SIZE_HELPER terminal_prep_terminal()
+#  endif  /* _WIN32 */
 #  define DEFAULT_TMPDIR       "c:/"
 #  define PATH_SEP     ";"
 #  define STRIP_DOT_EXE        1


diff -ubBwp -r texinfo-4.13.orig/info/dir.c texinfo-4.13/info/dir.c
--- texinfo-4.13.orig/info/dir.c        2008-06-12 16:39:20.000000000 +0300
+++ texinfo-4.13/info/dir.c     2011-11-02 12:32:10.970269800 +0200
@@ -40,7 +40,7 @@ static char *dirs_to_add[] = {
 
 
 /* Return zero if the file represented in the stat structure TEST has
-   already been seen, nonzero else.  */
+   already been seen, nonzero otherwise.  */
 
 typedef struct
 {
@@ -59,7 +59,10 @@ new_dir_file_p (struct stat *test)
     {
       dir_file_list_entry_type entry;
       entry = dir_file_list[i];
-      if (entry.device == test->st_dev && entry.inode == test->st_ino)
+      if (entry.device == test->st_dev && entry.inode == test->st_ino
+         /* On MS-Windows, `stat' returns zero as the inode, so we
+            effectively disable this optimization for that OS.  */
+         && entry.inode != 0)
         return 0;
     }
   

diff -ubBwp -r texinfo-4.13.orig/info/info.c texinfo-4.13/info/info.c
--- texinfo-4.13.orig/info/info.c       2008-08-16 03:17:04.000000000 +0300
+++ texinfo-4.13/info/info.c    2011-08-09 13:33:09.627126400 +0300
@@ -82,7 +82,7 @@ int raw_escapes_p = 1;
 /* Non-zero means print the absolute location of the file to be loaded.  */
 static int print_where_p = 0;
 
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
 /* Non-zero indicates that screen output should be made 'speech-friendly'.
    Since on MSDOS the usual behavior is to write directly to the video
    memory, speech synthesizer software cannot grab the output.  Therefore,
@@ -118,14 +118,14 @@ static struct option long_options[] = {
   { "version", 0, &print_version_p, 1 },
   { "vi-keys", 0, &vi_keys_p, 1 },
   { "where", 0, &print_where_p, 1 },
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
   { "speech-friendly", 0, &speech_friendly, 1 },
 #endif
   {NULL, 0, NULL, 0}
 };
 
 /* String describing the shorthand versions of the long options found above. */
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
 static char *short_options = "k:d:n:f:ho:ORswb";
 #else
 static char *short_options = "k:d:n:f:ho:ORws";
@@ -239,12 +239,12 @@ main (int argc, char *argv[])
           print_where_p = 1;
           break;
 
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
          /* User wants speech-friendly output.  */
        case 'b':
          speech_friendly = 1;
          break;
-#endif /* __MSDOS__ */
+#endif /* __MSDOS__ || __MINGW32__ */
 
           /* User has specified a string to search all indices for. */
         case 'k':
@@ -622,7 +622,7 @@ Options:\n\
       --restore=FILENAME       read initial keystrokes from FILENAME.\n\
   -O, --show-options, --usage  go to command-line options node."));
 
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
   puts (_("\
   -b, --speech-friendly        be friendly to speech synthesizers."));
 #endif

diff -ubBwp -r texinfo-4.13.orig/info/infokey.c texinfo-4.13/info/infokey.c
--- texinfo-4.13.orig/info/infokey.c    2008-06-12 16:39:20.000000000 +0300
+++ texinfo-4.13/info/infokey.c 2011-08-09 13:33:56.674001400 +0300
@@ -178,7 +178,7 @@ There is NO WARRANTY, to the extent perm
     char *homedir;
 
     homedir = getenv ("HOME");
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
     if (!homedir)
       homedir = ".";
 #endif

diff -ubBwp -r texinfo-4.13.orig/info/infomap.c texinfo-4.13/info/infomap.c
--- texinfo-4.13.orig/info/infomap.c    2008-06-12 16:39:21.000000000 +0300
+++ texinfo-4.13/info/infomap.c 2011-08-30 15:17:48.860949700 +0300
@@ -928,7 +928,7 @@ fetch_user_maps (void)
                 strcat(filename, "/");
                 strcat(filename, INFOKEY_FILE);
         }
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
         /* Poor baby, she doesn't have a HOME...  */
         else
                 filename = xstrdup(INFOKEY_FILE); /* try current directory */

diff -ubBwp -r texinfo-4.13.orig/info/man.c texinfo-4.13/info/man.c
--- texinfo-4.13.orig/info/man.c        2008-07-06 03:32:19.000000000 +0300
+++ texinfo-4.13/info/man.c     2011-07-25 15:15:38.299328900 +0300
@@ -20,7 +20,9 @@
    Originally written by Brian Fox Thu May  4 09:17:52 1995. */
 
 #include "info.h"
+#ifndef __MINGW32__
 #include <sys/ioctl.h>
+#endif
 #include "signals.h"
 #if defined (HAVE_SYS_TIME_H)
 #include <sys/time.h>

diff -ubBwp -r texinfo-4.13.orig/info/pcterm.c texinfo-4.13/info/pcterm.c
--- texinfo-4.13.orig/info/pcterm.c     2008-06-12 16:39:21.000000000 +0300
+++ texinfo-4.13/info/pcterm.c  2011-11-02 12:04:45.126519800 +0200
@@ -18,10 +18,11 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-/* WARNING WARNING WARNING!!!
-   This probably won't work as is with anything but DJGPP!  However, Borland
-   should come close, and other PC compilers will need minor modifications.  */
+/* WARNING WARNING WARNING!!!  This probably won't work as is with
+   anything but DJGPP and MinGW!  However, Borland should come close,
+   and other PC compilers will need minor modifications.  */
 
+#ifdef __MSDOS__
 /* intl/libintl.h defines a macro `gettext' which
    conflicts with conio.h header.  */
 #ifdef gettext
@@ -32,6 +33,42 @@
 #include <pc.h>
 #include <keys.h>
 #include <conio.h>
+#endif
+
+#ifdef _WIN32
+#include <io.h>
+#include <conio.h>
+#include <process.h>
+#include <windows.h>
+
+struct text_info {
+    WORD normattr;
+    WORD attribute;
+    SHORT winleft;
+    SHORT wintop;
+    SHORT winright;
+    SHORT winbottom;
+    SHORT screenheight;
+    SHORT screenwidth;
+    SHORT curx;
+    SHORT cury;
+    COORD bufsize;
+    unsigned char currmode;    /* unused and unsupported for Windows */
+};
+
+struct termios {
+  int dummy;
+};
+
+enum text_modes { LASTMODE=-1 };
+
+#define cprintf _cprintf
+#define cputs _cputs
+
+#undef read
+#undef _read
+
+#endif
 
 #include "variables.h"
 
@@ -44,10 +81,515 @@ extern int speech_friendly;        /* defined i
 /* **************************************************************** */
 
 static struct text_info outside_info;  /* holds screen params outside Info */
+#ifdef _WIN32
+static SHORT norm_attr, inv_attr;
+static SHORT current_attr;
+static HANDLE hstdin = INVALID_HANDLE_VALUE;
+static HANDLE hstdout = INVALID_HANDLE_VALUE;
+static HANDLE hinfo = INVALID_HANDLE_VALUE;
+static HANDLE hscreen = INVALID_HANDLE_VALUE;
+static DWORD old_inpmode;
+#else
 static unsigned char    norm_attr, inv_attr;
+#endif
 
 static unsigned const char * find_sequence (int);
 
+#ifdef _WIN32
+
+/* Windows-specific initialization and de-initialization.  */
+void
+w32_info_prep (void)
+{
+  SetConsoleActiveScreenBuffer (hinfo);
+  current_attr = norm_attr;
+  hscreen = hinfo;
+  SetConsoleMode (hstdin, ENABLE_WINDOW_INPUT);
+}
+
+void
+w32_info_unprep (void)
+{
+  SetConsoleActiveScreenBuffer (hstdout);
+  current_attr = outside_info.normattr;
+  hscreen = hstdout;
+  SetConsoleMode (hstdin, old_inpmode);
+}
+
+void
+w32_cleanup (void)
+{
+  CloseHandle (hinfo);
+}
+
+static void w32_info_init (void) __attribute__((constructor));
+
+static void
+w32_info_init (void)
+{
+  static void pc_initialize_terminal (char *);
+
+  /* We need to set this single hook here; the rest
+     will be set by pc_initialize_terminal when it is called.  */
+  terminal_initialize_terminal_hook = pc_initialize_terminal;
+}
+
+/* Emulate DJGPP conio functions for Windows.  */
+static void
+gettextinfo (struct text_info *ti)
+{
+  CONSOLE_SCREEN_BUFFER_INFO csbi;
+  static TCHAR errbuf[500];
+
+  hstdin = GetStdHandle (STD_INPUT_HANDLE);
+  hstdout = GetStdHandle (STD_OUTPUT_HANDLE);
+  hinfo = CreateConsoleScreenBuffer (GENERIC_READ | GENERIC_WRITE,
+                                    FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                    NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
+
+  if (hstdin != INVALID_HANDLE_VALUE
+      && hstdout != INVALID_HANDLE_VALUE
+      && hinfo != INVALID_HANDLE_VALUE
+      && GetConsoleMode (hstdin, &old_inpmode)
+      && GetConsoleScreenBufferInfo (hstdout, &csbi))
+    {
+      ti->normattr = csbi.wAttributes;
+      ti->winleft = 1;
+      ti->wintop = 1;
+      ti->winright = csbi.srWindow.Right + 1;
+      ti->winbottom = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+      ti->attribute = csbi.wAttributes;
+      ti->screenheight = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+      ti->screenwidth = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+      ti->curx = csbi.dwCursorPosition.X;
+      ti->cury = csbi.dwCursorPosition.Y;
+      ti->bufsize = csbi.dwSize;
+
+      atexit (w32_cleanup);
+    }
+  else
+    {
+      DWORD error_no = GetLastError ();
+
+      if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL,
+                         error_no,
+                         0, /* choose most suitable language */
+                         errbuf, sizeof (errbuf), NULL))
+       sprintf (errbuf, "w32 error %u", error_no);
+      CloseHandle (hinfo);
+      info_error (_("Terminal cannot be initialized: %s\n"), errbuf, NULL);
+      xexit (1);
+    }
+}
+
+void
+textattr (int attr)
+{
+  SetConsoleTextAttribute (hscreen, attr);
+}
+
+void
+textmode (int mode)
+{
+  /* Nothing.  */
+}
+
+void
+ScreenGetCursor (int *row, int *col)
+{
+  CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+  GetConsoleScreenBufferInfo (hscreen, &csbi);
+  *row = csbi.dwCursorPosition.Y;
+  *col = csbi.dwCursorPosition.X;
+}
+
+void
+ScreenSetCursor (int row, int col)
+{
+  COORD cursor_pos;
+
+  cursor_pos.X = col;
+  cursor_pos.Y = row;
+
+  SetConsoleCursorPosition (hscreen, cursor_pos);
+}
+
+void
+ScreenClear (void)
+{
+  DWORD nchars = screenwidth * screenheight;
+  COORD start_pos;
+  DWORD written;
+
+  start_pos.X = start_pos.Y = 0;
+  FillConsoleOutputAttribute (hscreen, norm_attr, nchars, start_pos, &written);
+  FillConsoleOutputCharacter (hscreen, ' ', nchars, start_pos, &written);
+}
+
+void
+clreol (void)
+{
+  DWORD nchars;
+  COORD start_pos;
+  DWORD written;
+  CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+  GetConsoleScreenBufferInfo (hscreen, &csbi);
+  start_pos = csbi.dwCursorPosition;
+  nchars = csbi.dwSize.X - start_pos.X;
+
+  FillConsoleOutputAttribute (hscreen, current_attr, nchars, start_pos,
+                             &written);
+  FillConsoleOutputCharacter (hscreen, ' ', nchars, start_pos, &written);
+}
+
+void
+ScreenVisualBell (void)
+{
+  DWORD nchars = screenwidth * screenheight;
+  COORD start_pos;
+  DWORD written;
+
+  start_pos.X = start_pos.Y = 0;
+  FillConsoleOutputAttribute (hscreen, inv_attr, nchars, start_pos, &written);
+  Sleep (20);
+  FillConsoleOutputAttribute (hscreen, norm_attr, nchars, start_pos, &written);
+}
+
+int
+movetext(int left, int top, int right, int bottom, int destleft, int desttop)
+{
+  SMALL_RECT src;
+  COORD dest;
+  CHAR_INFO fill;
+
+  src.Left = left - 1;
+  src.Top = top - 1;
+  src.Right = right - 1;
+  src.Bottom = bottom - 1;
+
+  dest.X = destleft - 1;
+  dest.Y = desttop - 1;
+
+  fill.Attributes = norm_attr;
+  fill.Char.AsciiChar = (CHAR)' ';
+
+  return ScrollConsoleScreenBuffer (hscreen, &src , NULL, dest, &fill) != 0;
+}
+
+int
+ScreenRows (void)
+{
+  CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+  GetConsoleScreenBufferInfo (hscreen, &csbi);
+  return csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+}
+
+int
+ScreenCols (void)
+{
+  CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+  GetConsoleScreenBufferInfo (hscreen, &csbi);
+  return csbi.srWindow.Right - csbi.srWindow.Left + 1;
+}
+
+void
+_set_screen_lines (int lines)
+{
+  SMALL_RECT window_rectangle;
+  CONSOLE_SCREEN_BUFFER_INFO csbi;
+  COORD scrbufsize;
+
+  GetConsoleScreenBufferInfo (hscreen, &csbi);
+
+  window_rectangle = csbi.srWindow;
+  window_rectangle.Bottom = window_rectangle.Top + lines - 1;
+  SetConsoleWindowInfo (hscreen, TRUE, &window_rectangle);
+
+  /* Set the screen buffer size to the same dimensions as the window,
+     so that the dysfunctional scroll bar disappears.  */
+  scrbufsize.X = window_rectangle.Right - window_rectangle.Left + 1;
+  scrbufsize.Y = window_rectangle.Bottom - window_rectangle.Top + 1;
+  SetConsoleScreenBufferSize (hscreen, scrbufsize);
+}
+
+void
+w32_set_screen_dimensions (int cols, int rows)
+{
+  SMALL_RECT window_rectangle;
+  CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+  GetConsoleScreenBufferInfo (hscreen, &csbi);
+
+  window_rectangle = csbi.srWindow;
+  window_rectangle.Bottom = window_rectangle.Top + rows - 1;
+  window_rectangle.Right = window_rectangle.Left + cols - 1;
+  SetConsoleWindowInfo (hscreen, TRUE, &window_rectangle);
+}
+
+/* Emulate `sleep'.  */
+unsigned
+sleep (unsigned sec)
+{
+  Sleep (sec*1000);
+  return 0;
+}
+
+/* Keyboard input support.  */
+
+static int
+w32_our_tty (int fd)
+{
+  return
+    isatty (fd)
+   /* Windows `isatty' actually tests for character devices, so the
+     null device gets reported as a tty.  Fix that by calling
+     `lseek'.  */
+    && lseek (fd, SEEK_CUR, 0) == -1
+    /* Is this our tty?  */
+    && hstdin != INVALID_HANDLE_VALUE
+    && hstdin == (HANDLE)_get_osfhandle (fd);
+}
+
+/* Translate a Windows key event into the equivalent sequence of bytes
+   to be submitted to Info dispatcher.  */
+#define define_seq(p,s1,s2)                                    \
+  do {                                                         \
+    if ((ctl & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0) \
+      memcpy (p, s1, sizeof (s1)), p += sizeof (s1) - 1;       \
+    else                                                       \
+      memcpy (p, s2, sizeof (s2)), p += sizeof (s2) - 1;       \
+  } while (0)
+
+static int
+w32keyseq (unsigned char ascii_ch, WORD vkey, DWORD ctl, unsigned char *seq)
+{
+  unsigned char *p = seq;
+
+  switch (ascii_ch)
+    {
+      case '\0':
+       /* Keys with no ASCII code are extended keys, like arrows.  */
+       switch (vkey)
+         {
+           case VK_PRIOR:
+             define_seq (p, "\033\061p", "\033v");
+             break;
+           case VK_NEXT:
+             define_seq (p, "\033\061n", "\026");
+             break;
+           case VK_END:
+             define_seq (p, "\033>", "\033>");
+             break;
+           case VK_HOME:
+             define_seq (p, "\033<", "\033<");
+             break;
+           case VK_LEFT:
+             define_seq (p, "\033b", "\033[D");
+             break;
+           case VK_UP:
+             define_seq (p, "\033\061u", "\033[A");
+             break;
+           case VK_RIGHT:
+             define_seq (p, "\033f", "\033[C");
+             break;
+           case VK_DOWN:
+             define_seq (p, "\033\061m", "\033[B");
+             break;
+           case VK_INSERT:
+             define_seq (p, "\033[L", "\033[L");
+             break;
+           case VK_DELETE:     /* Delete => Ctrl-d, Alt-Delete => ESC d */
+             if ((ctl & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0)
+               define_seq (p, "\033d", "\033d");
+             else
+               define_seq (p, "\033d", "\004");
+             break;
+           case VK_HELP:       /* F1 => Ctrl-h */
+           case VK_F1:
+             *p++ = '\010';
+             break;
+           case 50:            /* Ctrl-@ => '\0' */
+             if ((ctl & SHIFT_PRESSED) != 0)
+               *p++ = '\0';
+             break;
+           default:
+             if (0x41 <= vkey && vkey <= 0x5a)
+               {
+                 /* Alt-Ctrl-a, Alt-Ctrl-b, etc.  */
+                 *p++ = '\033';
+                 *p++ = '\001' + vkey - 0x41;
+               }
+         }
+       break;
+      case ' ':                        /* Ctrl-SPC => '\0' */
+       if ((ctl & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0)
+         ascii_ch = '\0';
+       *p++ = ascii_ch;
+       break;
+      case '\t':               /* Shift-TAB/Alt-TAB => Esc-TAB */
+       if ((ctl & (SHIFT_PRESSED | LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0)
+         {
+           memcpy (p, "\033\011", sizeof ("\033\011"));
+           p += sizeof ("\033\011") - 1;
+         }
+       else
+         *p++ = '\t';
+       break;
+      case '\b':
+       /* Backspace => DEL.  */
+       ascii_ch = '\177';
+       /* FALLTHROUGH */
+      default:
+       if ((ctl & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0)
+         *p++ = '\033';
+       *p++ = ascii_ch;
+       break;
+    }
+  return p - seq;
+}
+
+static unsigned char buffered_chars[512];
+static size_t buf_head;
+static size_t buf_tail;
+
+static ssize_t
+w32_kbd_read (unsigned char *inbuf, size_t n)
+{
+  DWORD nevents, nread;
+  INPUT_RECORD inrec;
+  ssize_t nret = 0;
+
+  do {
+
+    /* Stuff any unread buffered characters.  */
+    while (buf_head < buf_tail && n > 0)
+      {
+       *inbuf++ = buffered_chars[buf_head++];
+       nret++;
+       n--;
+      }
+    if (n <= 0)
+      break;
+
+    /* Wait for input.  */
+    while (GetNumberOfConsoleInputEvents (hstdin, &nevents)
+          && nevents < 1)
+      Sleep (20);
+
+    while (nevents-- && n > 0)
+      {
+       if (!ReadConsoleInput (hstdin, &inrec, 1, &nread))
+         return -1;
+
+       if (nread > 0)
+         {
+           switch (inrec.EventType)
+             {
+               case KEY_EVENT:
+                 if (inrec.Event.KeyEvent.bKeyDown == TRUE
+                     && !(inrec.Event.KeyEvent.wVirtualScanCode == 0
+                          || inrec.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT
+                          || inrec.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL
+                          || inrec.Event.KeyEvent.wVirtualKeyCode == VK_MENU))
+                   {
+                     unsigned char keyseq[10];
+                     int count = inrec.Event.KeyEvent.wRepeatCount;
+                     unsigned char ch = inrec.Event.KeyEvent.uChar.AsciiChar;
+                     WORD vkey = inrec.Event.KeyEvent.wVirtualKeyCode;
+                     DWORD ctl_state = inrec.Event.KeyEvent.dwControlKeyState;
+                     int nbytes = w32keyseq (ch, vkey, ctl_state, keyseq);
+
+                     /* Supply up to N characters to the caller.  */
+                     while (count && n >= nbytes)
+                       {
+                         if (nbytes == 1 && keyseq[0] == '\032')
+                           {
+                             terminal_goto_xy (0, screenheight - 1);
+                             terminal_clear_to_eol ();
+                             fflush (stdout);
+                             terminal_unprep_terminal ();
+                             kill (getpid (), 0);
+                             terminal_prep_terminal ();
+                             reset_info_window_sizes ();
+                           }
+                         else
+                           {
+                             memcpy (&inbuf[nret], keyseq, nbytes);
+                             nret += nbytes;
+                             n -= nbytes;
+                           }
+                         count--;
+                       }
+                     /* Buffer the rest.  */
+                     if (count > 0)
+                       {
+                         buf_head = buf_tail = 0;
+                         while (count--
+                                && buf_tail < sizeof(buffered_chars) - nbytes)
+                           {
+                             memcpy (&buffered_chars[buf_tail], keyseq, 
nbytes);
+                             buf_tail += nbytes;
+                           }
+                       }
+                   }
+                 break;
+               case WINDOW_BUFFER_SIZE_EVENT:
+                 {
+                   int rows, cols;
+
+                   /* Note: this event is only sent when the console
+                      window's _screen_buffer_ size is changed via
+                      the Properties->Layout dialog.  */
+                   cols = inrec.Event.WindowBufferSizeEvent.dwSize.X;
+                   rows = inrec.Event.WindowBufferSizeEvent.dwSize.Y;
+                   screenwidth = cols;
+                   screenheight = rows;
+                   w32_set_screen_dimensions (cols, rows);
+                   display_initialize_display (screenwidth, screenheight);
+                   window_new_screen_size (screenwidth, screenheight);
+                   redisplay_after_signal ();
+                 }
+                 break;
+               default:
+                 break;
+             }
+         }
+      }
+  } while (n > 0);
+  return nret;
+}
+
+long
+w32_chars_avail (int fd)
+{
+  if (w32_our_tty (fd))
+    return buf_tail - buf_head;
+  else
+    {
+      struct stat st;
+
+      if (fstat (fd, &st) < 0)
+       return 1;
+      else
+       return st.st_size;
+    }
+}
+
+ssize_t
+w32_read (int fd, void *buf, size_t n)
+{
+  if (w32_our_tty (fd))
+    return w32_kbd_read (buf, n);
+  else
+    return _read (fd, buf, n);
+}
+
+#endif /* _WIN32 */
+
 /* Turn on reverse video. */
 static void
 pc_begin_inverse (void)
@@ -192,6 +734,10 @@ pc_prep_terminal (void)
 {
   int tty;
 
+#ifdef _WIN32
+  w32_info_prep ();
+#endif
+
   /* Do not set screen height if we already have it, because
      doing so erases the screen.  */
   if (screenheight != ScreenRows ())
@@ -221,6 +767,10 @@ pc_unprep_terminal (void)
 {
   int tty;
 
+#ifdef _WIN32
+  w32_info_unprep ();
+#endif
+
   textattr (outside_info.normattr);
 
   /* Do not set screen height if we already have it, because
@@ -230,8 +780,13 @@ pc_unprep_terminal (void)
       _set_screen_lines (outside_info.screenheight);
       textmode (LASTMODE);
     }
+#ifdef __MSDOS__
   else
     pc_clear_to_eol ();        /* for text attributes to really take effect */
+#endif
+#ifdef _WIN32
+  SetConsoleScreenBufferSize (hstdout, outside_info.bufsize);
+#endif
 
   /* Switch back to text mode on stdin.  */
   tty = fileno (stdin);
@@ -256,7 +811,12 @@ pc_initialize_terminal (term_name)
     {
       term_name = getenv ("TERM");
       if (!term_name)
+#ifdef __MSDOS__
        term_name = "pc-dos";   /* ``what's in a name?'' */
+#endif
+#ifdef _WIN32
+       term_name = "w32console";
+#endif
     }
 
   /* Get current video information, to be restored later.  */
@@ -311,6 +871,7 @@ pc_initialize_terminal (term_name)
 
   pc_get_screen_size ();
 
+#ifdef __MSDOS__
   /* Store the arrow keys.  */
   term_ku = (char *)find_sequence (K_Up);
   term_kd = (char *)find_sequence (K_Down);
@@ -326,6 +887,7 @@ pc_initialize_terminal (term_name)
   term_ki = (char *)find_sequence (K_Insert);
   term_kx = (char *)find_sequence (K_Delete);
 #endif
+#endif /* __MSDOS__ */
 
   /* Set all the hooks to our PC-specific functions.  */
   terminal_begin_inverse_hook       = pc_begin_inverse;
@@ -687,9 +1249,11 @@ kill (pid_t pid, int sig)
          xexit (1);
        case SIGUSR1:
          /* Simulate SIGTSTP by invoking a subsidiary shell.  */
+#ifndef _WIN32
          pc_goto_xy (0, outside_info.screenheight - 1);
          pc_clear_to_eol ();
          pc_write_chars (stopped_msg, sizeof (stopped_msg) - 1);
+#endif
 
          /* The child shell can change the working directory, so
             we need to save and restore it, since it is global.  */
@@ -699,7 +1263,26 @@ kill (pid_t pid, int sig)
          /* We don't want to get fatal signals while the subshell runs.  */
          old_INT = signal (SIGINT, SIG_IGN);
          old_QUIT = signal (SIGQUIT, SIG_IGN);
+#ifdef _WIN32
+         {
+           const char *argv[2];
+           const char *shell = NULL;
+
+           argv[0] = NULL;
+           shell = getenv ("SHELL");
+           if (!shell)
+             {
+               shell = getenv ("COMSPEC");
+               if (!shell)
+                 return -1;
+               argv[0] = " /k";
+             }
+           argv[1] = NULL;
+           _spawnvp (_P_WAIT, shell, argv);
+         }
+#else
          system ("");
+#endif
          if (*cwd)
            chdir (cwd);
          signal (SIGINT, old_INT);

diff -ubBwp -r texinfo-4.13.orig/info/session.c texinfo-4.13/info/session.c
--- texinfo-4.13.orig/info/session.c    2008-06-12 16:39:21.000000000 +0300
+++ texinfo-4.13/info/session.c 2011-08-10 09:26:30.908438400 +0300
@@ -21,7 +21,13 @@
 
 #include "info.h"
 #include "search.h"
+#ifndef __MINGW32__
 #include <sys/ioctl.h>
+#endif
+#ifdef __MINGW32__
+# define read(f,b,s)   w32_read(f,b,s)
+# define _read(f,b,s)  w32_read(f,b,s)
+#endif
 
 #if defined (HAVE_SYS_TIME_H)
 #  include <sys/time.h>
@@ -5373,6 +5379,19 @@ info_gather_typeahead (void)
     if (chars_avail)
       chars_avail = read (tty, &input[0], chars_avail);
   }
+#   else
+#    ifdef __MINGW32__
+  {
+    extern long w32_chars_avail (int);
+
+    chars_avail = w32_chars_avail (tty);
+
+    if (chars_avail > space_avail)
+      chars_avail = space_avail;
+    if (chars_avail)
+      chars_avail = read (tty, &input[0], chars_avail);
+  }
+#    endif  /* _WIN32 */
 #   endif/* __DJGPP__ */
 #  endif /* O_NDELAY */
 #endif /* !FIONREAD */

diff -ubBwp -r texinfo-4.13.orig/info/signals.c texinfo-4.13/info/signals.c
--- texinfo-4.13.orig/info/signals.c    2007-07-02 01:20:31.000000000 +0300
+++ texinfo-4.13/info/signals.c 2011-11-01 15:35:24.065452900 +0200
@@ -151,7 +151,7 @@ initialize_info_signal_handler (void)
 #endif
 }
 
-static void
+void
 redisplay_after_signal (void)
 {
   terminal_clear_screen ();
@@ -162,7 +162,7 @@ redisplay_after_signal (void)
   fflush (stdout);
 }
 
-static void
+void
 reset_info_window_sizes (void)
 {
   terminal_goto_xy (0, 0);

diff -ubBwp -r texinfo-4.13.orig/info/termdep.h texinfo-4.13/info/termdep.h
--- texinfo-4.13.orig/info/termdep.h    2007-07-02 01:20:31.000000000 +0300
+++ texinfo-4.13/info/termdep.h 2011-08-10 09:13:14.834416600 +0300
@@ -43,7 +43,9 @@
 #      endif /* M_XENIX */
 #    endif /* HAVE_SYS_PTEM_H */
 #  else /* !HAVE_TERMIO_H */
+#    ifndef __MINGW32__
 #    include <sgtty.h>
+#    endif
 #  endif /* !HAVE_TERMIO_H */
 #endif /* !HAVE_TERMIOS_H */
 
@@ -55,4 +57,8 @@
 #  include <sys/ttold.h>
 #endif /* HAVE_SYS_TTOLD_H */
 
+#ifdef _WIN32
+extern unsigned sleep (unsigned);
+#endif
+
 #endif /* not INFO_TERMDEP_H */

diff -ubBwp -r texinfo-4.13.orig/info/terminal.c texinfo-4.13/info/terminal.c
--- texinfo-4.13.orig/info/terminal.c   2008-06-12 16:39:21.000000000 +0300
+++ texinfo-4.13/info/terminal.c        2011-08-08 09:10:12.985566800 +0300
@@ -572,7 +572,9 @@ terminal_initialize_terminal (char *term
       ospeed = B9600;
   }
 # else
+#ifndef __MINGW32__
   ospeed = B9600;
+#endif
 # endif /* !TIOCGETP */
 #endif
 
@@ -663,7 +665,9 @@ struct termio original_termio, ttybuff;
 /* Buffers containing the terminal mode flags upon entry to info. */
 int original_tty_flags = 0;
 int original_lmode;
+#ifndef __MINGW32__
 struct sgttyb ttybuff;
+#endif
 
 #    if defined(TIOCGETC) && defined(M_XENIX)
 /* SCO 3.2v5.0.2 defines but does not support TIOCGETC.  Gak.  Maybe
@@ -758,7 +762,7 @@ terminal_prep_terminal (void)
 #  endif
 #endif
 
-#if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H)
+#if !defined (HAVE_TERMIOS_H) && !defined (HAVE_TERMIO_H) && 
!defined(__MINGW32__)
   ioctl (tty, TIOCGETP, &ttybuff);
 
   if (!original_tty_flags)
@@ -819,9 +823,11 @@ terminal_prep_terminal (void)
   }
 #  endif /* TIOCGLTC */
 
+# ifndef __MINGW32__
   ttybuff.sg_flags &= ~ECHO;
   ttybuff.sg_flags |= CBREAK;
   ioctl (tty, TIOCSETN, &ttybuff);
+# endif
 #endif /* !HAVE_TERMIOS_H && !HAVE_TERMIO_H */
 }
 
@@ -846,9 +852,11 @@ terminal_unprep_terminal (void)
 #  if defined (HAVE_TERMIO_H)
   ioctl (tty, TCSETA, &original_termio);
 #  else /* !HAVE_TERMIO_H */
+#   ifndef __MINGW32__
   ioctl (tty, TIOCGETP, &ttybuff);
   ttybuff.sg_flags = original_tty_flags;
   ioctl (tty, TIOCSETN, &ttybuff);
+#   endif
 
 #  if defined (TIOCGETC)
   ioctl (tty, TIOCSETC, &original_tchars);
@@ -867,6 +875,6 @@ terminal_unprep_terminal (void)
   terminal_end_using_terminal ();
 }
 
-#ifdef __MSDOS__
+#if defined(__MSDOS__) || defined(__MINGW32__)
 # include "pcterm.c"
 #endif

diff -ubBwp -r texinfo-4.13.orig/info/tilde.c texinfo-4.13/info/tilde.c
--- texinfo-4.13.orig/info/tilde.c      2008-06-12 16:39:21.000000000 +0300
+++ texinfo-4.13/info/tilde.c   2011-08-02 10:23:50.080731400 +0300
@@ -190,11 +190,15 @@ tilde_expand_word (char *filename)
              the password database. */
           if (!temp_home)
             {
+#ifndef __MINGW32__
               struct passwd *entry;
 
               entry = (struct passwd *) getpwuid (getuid ());
               if (entry)
                 temp_home = entry->pw_dir;
+#else
+             temp_home = ".";
+#endif
             }
 
           temp_name = xmalloc (1 + strlen (&dirname[1])
@@ -210,7 +214,9 @@ tilde_expand_word (char *filename)
         }
       else
         {
+#ifndef __MINGW32__
           struct passwd *user_entry;
+#endif
           char *username = xmalloc (257);
           int i, c;
 
@@ -223,6 +229,7 @@ tilde_expand_word (char *filename)
             }
           username[i - 1] = 0;
 
+#ifndef __MINGW32__
           if (!(user_entry = (struct passwd *) getpwnam (username)))
             {
               /* If the calling program has a special syntax for
@@ -259,6 +266,24 @@ tilde_expand_word (char *filename)
 
           endpwent ();
           free (username);
+#else
+         if (tilde_expansion_failure_hook)
+           {
+             char *expansion = (*tilde_expansion_failure_hook) (username);
+
+             if (expansion)
+               {
+                 temp_name = xmalloc (1 + strlen (expansion)
+                                      + strlen (&dirname[i]));
+                 strcpy (temp_name, expansion);
+                 strcat (temp_name, &dirname[i]);
+                 free (expansion);
+               }
+           }
+         free (dirname);
+         dirname = xstrdup (temp_name);
+         free (temp_name);
+#endif
         }
     }
   return dirname;


--- texinfo-4.13.orig/info/man.c        2011-07-25 15:15:38.299328900 +0300
+++ texinfo-4.13/info/man.c     2012-01-08 08:26:45.674020200 +0200
@@ -294,7 +294,7 @@ get_manpage_contents (char *pagename)
   if (manpage_section)
     formatter_args[arg_index++] = manpage_section;
   else
-    formatter_args[arg_index++] = "-a";    
+    formatter_args[arg_index++] = "-a";
 
   formatter_args[arg_index++] = manpage_pagename;
   formatter_args[arg_index] = NULL;
@@ -339,17 +339,23 @@ get_manpage_contents (char *pagename)
   /* Cannot fork/exec, but can popen/pclose.  */
   {
     FILE *fpipe;
-    char *cmdline = xmalloc (strlen (formatter_args[0])
-                            + strlen (manpage_pagename)
-                            + (arg_index > 2 ? strlen (manpage_section) : 0)
-                            + 3);
+    char *cmdline;
+    size_t cmdlen = 0;
     int save_stderr = dup (fileno (stderr));
     int fd_err = open (NULL_DEVICE, O_WRONLY, 0666);
+    int i;
+
+    for (i = 0; i < arg_index; i++)
+      cmdlen += strlen (formatter_args[i]);
+    /* Add-ons: 2 blanks, 2 quotes for the formatter program, 1
+       terminating null character.  */
+    cmdlen += 2 + 2 + 1;
+    cmdline = xmalloc (cmdlen);
 
     if (fd_err > 2)
       dup2 (fd_err, fileno (stderr)); /* Don't print errors. */
-    sprintf (cmdline, "%s %s %s", formatter_args[0], manpage_pagename,
-                                 arg_index > 2 ? manpage_section : "");
+    sprintf (cmdline, "\"%s\" %s %s",
+            formatter_args[0], formatter_args[1], formatter_args[2]);
     fpipe = popen (cmdline, "r");
     free (cmdline);
     if (fd_err > 2)


diff -ubBwp -r texinfo-4.13.orig/makeinfo/index.c texinfo-4.13/makeinfo/index.c
--- texinfo-4.13.orig/makeinfo/index.c  2008-05-22 16:11:34.000000000 +0300
+++ texinfo-4.13/makeinfo/index.c       2011-07-25 12:27:14.970722900 +0300
@@ -48,6 +48,8 @@ INDEX_ALIST **name_index_alist = NULL;
    command changes which array slot is pointed to by a given index.  */
 static INDEX_ELT **the_indices = NULL;
 
+int mbscasecmp (const char *, const char *);
+
 /* How to compare index entries for sorting.  May be set to strcoll.  */
 static int (*index_compare_fn) (const char *a, const char *b) = mbscasecmp;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]