[Top][All Lists]
[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;
- MS-Windows build of Texinfo,
Eli Zaretskii <=