On Fri, Sep 11, 2009 at 01:14:39AM +0200, Vincent van Ravesteijn wrote:
> >
> >> You don't need Cygwin to test it.
> >>
> >> 1. Use "\\.\pipe\lyxpipe" (without quotes) as the LyXserver pipe path
> >>    in the preferences.
> >> 2. Quit and restart LyX.
> >> 3. In a cmd.exe terminal type
> >>      echo LYXCMD:test:file-open> \\.\pipe\lyxpipe.in
> >>      type \\.\pipe\lyxpipe.out
> >>
> >> If the file dialog opens, it works.
> > This doesn't work. I get an error message: "LyXComm: The parameter is 
> > invalid", or ERROR_INVALID_PARAMETER in server....@294.
> >
> > If I do the following it works (but it'll not be the correct fix, but 
> > you know at least that it works in this case):
> >
> > server....@280--282:
> >    success = ReadFile(pipe_[i].handle,
> >        pipe_[i].readbuf, PIPE_BUFSIZE - 1,
> > +       &pipe_[i].nbytes, &pipe_[i].overlap);
> > -       &pipe_[i].nbytes, NULL);
> >   
> 
> The following fixes it for me:
> 
>      bool LyXComm::startPipe(DWORD index)
>      {
>            pipe_[index].pending_io = false;
>    
> +         pipe_[index].overlap.Offset = 0;
> +         pipe_[index].overlap.OffsetHigh = 0;
> 
> 
> see http://msdn.microsoft.com/en-us/library/aa365603(VS.85).aspx and 
> scroll down to the third comment:

I was actually following that example but somehow missed the comment :(
I wonder why it was working for me. Could it be a gcc vs msvc issue?
Thanks for spotting. Updated patch attached.

-- 
Enrico
Index: src/Makefile.am
===================================================================
--- src/Makefile.am     (revision 31369)
+++ src/Makefile.am     (working copy)
@@ -5,6 +5,7 @@ include $(top_srcdir)/config/common.am
 DISTCLEANFILES += config.h libintl.h
 
 AM_CPPFLAGS += $(PCH_FLAGS) -I$(top_srcdir)/src $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(QT4_CPPFLAGS) $(QT4_CORE_INCLUDES)
 
 if BUILD_CLIENT_SUBDIR
 CLIENT = client
@@ -289,6 +290,22 @@ liblyxcore_la_SOURCES = $(SOURCEFILESCOR
 
 endif
 
+if INSTALL_WINDOWS
+
+MOCHEADER = Server.h
+
+MOCEDFILES = $(MOCHEADER:%.h=%_moc.cpp)
+
+BUILT_SOURCES += $(MOCEDFILES)
+CLEANFILES += $(MOCEDFILES)
+
+%_moc.cpp: %.h
+       $(MOC4) -D_WIN32 -o $@ $<
+
+liblyxcore_la_DEPENDENCIES = $(MOCEDFILES)
+
+endif
+
 ############################### Graphics ##############################
 
 noinst_LTLIBRARIES += liblyxgraphics.la
Index: src/LyXFunc.cpp
===================================================================
--- src/LyXFunc.cpp     (revision 31369)
+++ src/LyXFunc.cpp     (working copy)
@@ -1168,6 +1168,7 @@ void LyXFunc::dispatch(FuncRequest const
                        int row;
                        istringstream is(argument);
                        is >> file_name >> row;
+                       file_name = os::internal_path(file_name);
                        Buffer * buf = 0;
                        bool loaded = false;
                        string const abstmp = 
package().temp_dir().absFilename();
Index: src/Server.cpp
===================================================================
--- src/Server.cpp      (revision 31369)
+++ src/Server.cpp      (working copy)
@@ -7,6 +7,7 @@
  * \author Jean-Marc Lasgouttes
  * \author Angus Leeming
  * \author John Levon
+ * \author Enrico Forestieri
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -48,10 +49,16 @@
 
 #include "support/debug.h"
 #include "support/FileName.h"
+#include "support/lassert.h"
 #include "support/lstrings.h"
+#include "support/os.h"
 
 #include <boost/bind.hpp>
 
+#ifdef _WIN32
+#include <QCoreApplication>
+#endif
+
 #include <cerrno>
 #ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
@@ -60,6 +67,7 @@
 
 using namespace std;
 using namespace lyx::support;
+using os::external_path;
 
 namespace lyx {
 
@@ -69,7 +77,607 @@ namespace lyx {
 //
 /////////////////////////////////////////////////////////////////////
 
-#if !defined (HAVE_MKFIFO)
+#if defined(_WIN32)
+
+class ReadReadyEvent : public QEvent {
+public:
+       ///
+       ReadReadyEvent(DWORD inpipe) : QEvent(QEvent::User), inpipe_(inpipe)
+       {}
+       ///
+       DWORD inpipe() const { return inpipe_; }
+
+private:
+       DWORD inpipe_;
+};
+
+namespace {
+
+string errormsg(DWORD const error)
+{
+       void * msgbuf;
+       string message;
+       if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                         FORMAT_MESSAGE_FROM_SYSTEM |
+                         FORMAT_MESSAGE_IGNORE_INSERTS,
+                         NULL, error,
+                         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                         (LPTSTR) &msgbuf, 0, NULL)) {
+               message = static_cast<char *>(msgbuf);
+               LocalFree(msgbuf);
+       } else
+               message = "Unknown error";
+
+       return message;
+}
+
+} // namespace anon
+
+
+DWORD WINAPI pipeServerWrapper(void * arg)
+{
+       LyXComm * lyxcomm = reinterpret_cast<LyXComm *>(arg);
+       if (!lyxcomm->pipeServer()) {
+               // Error exit; perform cleanup.
+               lyxcomm->ready_ = false;
+               lyxcomm->closeHandles();
+               CloseHandle(lyxcomm->server_thread_);
+               CloseHandle(lyxcomm->stopserver_);
+               CloseHandle(lyxcomm->outbuf_mutex_);
+               lyxerr << "LyXComm: Closing connection" << endl;
+       }
+       return 1;
+}
+
+
+LyXComm::LyXComm(string const & pip, Server * cli, ClientCallbackfct ccb)
+       : pipename_(pip), client_(cli), clientcb_(ccb), stopserver_(0)
+{
+       for (int i = 0; i < MAX_PIPES; ++i) {
+               event_[i] = 0;
+               pipe_[i].handle = INVALID_HANDLE_VALUE;
+       }
+       ready_ = false;
+       openConnection();
+}
+
+
+bool LyXComm::pipeServer()
+{
+       DWORD i;
+       DWORD error;
+
+       for (i = 0; i < MAX_PIPES; ++i) {
+               bool const is_outpipe = i >= MAX_CLIENTS;
+               DWORD const open_mode = is_outpipe ? PIPE_ACCESS_OUTBOUND
+                                                  : PIPE_ACCESS_INBOUND;
+               string const pipename = external_path(pipeName(i));
+
+               // Manual-reset event, initial state = signaled
+               event_[i] = CreateEvent(NULL, TRUE, TRUE, NULL);
+               if (!event_[i]) {
+                       error = GetLastError();
+                       lyxerr << "LyXComm: Could not create event for pipe "
+                              << pipename << "\nLyXComm: "
+                              << errormsg(error) << endl;
+                       return false;
+               }
+
+               pipe_[i].overlap.hEvent = event_[i];
+               pipe_[i].iobuf.erase();
+               pipe_[i].handle = CreateNamedPipe(pipename.c_str(),
+                               open_mode | FILE_FLAG_OVERLAPPED, PIPE_WAIT,
+                               MAX_CLIENTS, PIPE_BUFSIZE, PIPE_BUFSIZE,
+                               PIPE_TIMEOUT, NULL);
+
+               if (pipe_[i].handle == INVALID_HANDLE_VALUE) {
+                       error = GetLastError();
+                       lyxerr << "LyXComm: Could not create pipe "
+                              << pipename << "\nLyXComm: "
+                              << errormsg(error) << endl;
+                       return false;
+               }
+
+               if (!startPipe(i))
+                       return false;
+               pipe_[i].state = pipe_[i].pending_io ?
+                       CONNECTING_STATE : (is_outpipe ? WRITING_STATE
+                                                      : READING_STATE);
+       }
+
+       // Add the stopserver_ event
+       event_[MAX_PIPES] = stopserver_;
+
+       // We made it!
+       LYXERR(Debug::LYXSERVER, "LyXComm: Connection established");
+       ready_ = true;
+       outbuf_.erase();
+       DWORD status;
+       bool success;
+
+       while (!checkStopServer()) {
+               // Indefinitely wait for the completion of an overlapped
+               // read, write, or connect operation.
+               DWORD wait = WaitForMultipleObjects(MAX_PIPES + 1, event_,
+                                                   FALSE, INFINITE);
+
+               // Determine which pipe instance completed the operation.
+               i = wait - WAIT_OBJECT_0;
+               LASSERT(i >= 0 && i <= MAX_PIPES, /**/);
+
+               // Check whether we were waked up for stopping the pipe server.
+               if (i == MAX_PIPES)
+                       break;
+
+               bool const is_outpipe = i >= MAX_CLIENTS;
+
+               // Get the result if the operation was pending.
+               if (pipe_[i].pending_io) {
+                       success = GetOverlappedResult(pipe_[i].handle,
+                                       &pipe_[i].overlap, &status, FALSE);
+
+                       switch (pipe_[i].state) {
+                       case CONNECTING_STATE:
+                               // Pending connect operation
+                               if (!success) {
+                                       error = GetLastError();
+                                       lyxerr << "LyXComm: "
+                                              << errormsg(error) << endl;
+                                       if (!resetPipe(i, true))
+                                               return false;
+                                       continue;
+                               }
+                               pipe_[i].state = is_outpipe ? WRITING_STATE
+                                                           : READING_STATE;
+                               break;
+
+                       case READING_STATE:
+                               // Pending read operation
+                               LASSERT(!is_outpipe, /**/);
+                               if (!success || status == 0) {
+                                       if (!resetPipe(i, !success))
+                                               return false;
+                                       continue;
+                               }
+                               pipe_[i].nbytes = status;
+                               pipe_[i].state = WRITING_STATE;
+                               break;
+
+                       case WRITING_STATE:
+                               // Pending write operation
+                               LASSERT(is_outpipe, /**/);
+                               // Let's see whether we have a reply
+                               if (!outbuf_.empty()) {
+                                       // Yep. Deliver it to all pipe
+                                       // instances if we get ownership
+                                       // of the mutex, otherwise we'll
+                                       // try again the next round.
+                                       DWORD result = WaitForSingleObject(
+                                                       outbuf_mutex_, 200);
+                                       if (result == WAIT_OBJECT_0) {
+                                               DWORD j = MAX_CLIENTS;
+                                               while (j < MAX_PIPES) {
+                                                       pipe_[j].iobuf = 
outbuf_;
+                                                       ++j;
+                                               }
+                                               outbuf_.erase();
+                                       }
+                                       ReleaseMutex(outbuf_mutex_);
+                               }
+                               if (pipe_[i].iobuf.empty())
+                                       pipe_[i].pending_io = false;
+                               break;
+                       }
+               }
+
+               // Operate according to the pipe state
+               switch (pipe_[i].state) {
+               case READING_STATE:
+                       // The pipe instance is connected to a client
+                       // and is ready to read a request.
+                       LASSERT(!is_outpipe, /**/);
+                       success = ReadFile(pipe_[i].handle,
+                                       pipe_[i].readbuf, PIPE_BUFSIZE - 1,
+                                       &pipe_[i].nbytes, &pipe_[i].overlap);
+
+                       if (success && pipe_[i].nbytes != 0) {
+                               // The read operation completed successfully.
+                               pipe_[i].pending_io = false;
+                               pipe_[i].state = WRITING_STATE;
+                               continue;
+                       }
+
+                       error = GetLastError();
+
+                       if (!success && error == ERROR_IO_PENDING) {
+                               // The read operation is still pending.
+                               pipe_[i].pending_io = true;
+                               continue;
+                       }
+
+                       success = error == ERROR_BROKEN_PIPE;
+
+                       // Client closed connection (ERROR_BROKEN_PIPE) or
+                       // an error occurred; in either case, reset the pipe.
+                       if (!success) {
+                               lyxerr << "LyXComm: " << errormsg(error) << 
endl;
+                               if (!pipe_[i].iobuf.empty()) {
+                                       lyxerr << "LyXComm: truncated command: "
+                                              << pipe_[i].iobuf << endl;
+                                       pipe_[i].iobuf.erase();
+                               }
+                       }
+                       if (!resetPipe(i, !success))
+                               return false;
+                       break;
+
+               case WRITING_STATE:
+                       if (!is_outpipe) {
+                               // The request was successfully read
+                               // from the client; commit it.
+                               ReadReadyEvent * event = new ReadReadyEvent(i);
+                               QCoreApplication::postEvent(this,
+                                               static_cast<QEvent *>(event));
+                               // Wait for completion
+                               while (pipe_[i].nbytes && !checkStopServer(100))
+                                       ;
+                               pipe_[i].pending_io = false;
+                               pipe_[i].state = READING_STATE;
+                               continue;
+                       }
+
+                       // This is an output pipe instance. Initiate the
+                       // overlapped write operation or monitor its progress.
+
+                       if (pipe_[i].pending_io) {
+                               success = WriteFile(pipe_[i].handle,
+                                               pipe_[i].iobuf.c_str(),
+                                               pipe_[i].iobuf.length(),
+                                               &status,
+                                               &pipe_[i].overlap);
+                       }
+
+                       if (success && !pipe_[i].iobuf.empty()
+                           && status == pipe_[i].iobuf.length()) {
+                               // The write operation completed successfully.
+                               pipe_[i].iobuf.erase();
+                               pipe_[i].pending_io = false;
+                               if (!resetPipe(i))
+                                       return false;
+                               continue;
+                       }
+
+                       error = GetLastError();
+
+                       if (success && error == ERROR_IO_PENDING) {
+                               // The write operation is still pending.
+                               // We get here when a reader is started
+                               // well before a reply is ready, so delay
+                               // a bit in order to not burden the cpu.
+                               checkStopServer(100);
+                               pipe_[i].pending_io = true;
+                               continue;
+                       }
+
+                       success = error == ERROR_NO_DATA;
+
+                       // Client closed connection (ERROR_NO_DATA) or
+                       // an error occurred; in either case, reset the pipe.
+                       if (!success) {
+                               lyxerr << "LyXComm: Error sending message: "
+                                      << pipe_[i].iobuf << "\nLyXComm: "
+                                      << errormsg(error) << endl;
+                       }
+                       if (!resetPipe(i, !success))
+                               return false;
+                       break;
+               }
+       }
+
+       ready_ = false;
+       closeHandles();
+       return true;
+}
+
+
+void LyXComm::closeHandles()
+{
+       for (int i = 0; i < MAX_PIPES; ++i) {
+               if (event_[i]) {
+                       ResetEvent(event_[i]);
+                       CloseHandle(event_[i]);
+                       event_[i] = 0;
+               }
+               if (pipe_[i].handle != INVALID_HANDLE_VALUE) {
+                       CloseHandle(pipe_[i].handle);
+                       pipe_[i].handle = INVALID_HANDLE_VALUE;
+               }
+       }
+}
+
+
+bool LyXComm::event(QEvent * e)
+{
+       if (e->type() == QEvent::User) {
+               read_ready(static_cast<ReadReadyEvent *>(e)->inpipe());
+               return true;
+       }
+       return false;
+}
+
+
+bool LyXComm::checkStopServer(DWORD timeout)
+{
+       return WaitForSingleObject(stopserver_, timeout) == WAIT_OBJECT_0;
+}
+
+
+bool LyXComm::startPipe(DWORD index)
+{
+       pipe_[index].pending_io = false;
+       pipe_[index].overlap.Offset = 0;
+       pipe_[index].overlap.OffsetHigh = 0;
+
+       // Overlapped ConnectNamedPipe should return zero.
+       if (ConnectNamedPipe(pipe_[index].handle, &pipe_[index].overlap)) {
+               DWORD const error = GetLastError();
+               lyxerr << "LyXComm: Could not connect pipe "
+                      << external_path(pipeName(index))
+                      << "\nLyXComm: " << errormsg(error) << endl;
+               return false;
+       }
+
+       switch (GetLastError()) {
+       case ERROR_IO_PENDING:
+               // The overlapped connection is in progress.
+               pipe_[index].pending_io = true;
+               break;
+
+       case ERROR_PIPE_CONNECTED:
+               // Client is already connected, so signal an event.
+               if (SetEvent(pipe_[index].overlap.hEvent))
+                       break;
+               // fall through
+       default:
+               // Anything else is an error.
+               DWORD const error = GetLastError();
+               lyxerr << "LyXComm: An error occurred while connecting pipe "
+                      << external_path(pipeName(index))
+                      << "\nLyXComm: " << errormsg(error) << endl;
+               return false;
+       }
+
+       return true;
+}
+
+
+bool LyXComm::resetPipe(DWORD index, bool close_handle)
+{
+       // This method is called when an error occurs or when a client
+       // closes the connection. We first disconnect the pipe instance,
+       // then reconnect it, ready to wait for another client.
+
+       if (!DisconnectNamedPipe(pipe_[index].handle)) {
+               DWORD const error = GetLastError();
+               lyxerr << "LyXComm: Could not disconnect pipe "
+                      << external_path(pipeName(index))
+                      << "\nLyXComm: " << errormsg(error) << endl;
+               // What to do now? Let's try whether re-creating the pipe helps.
+               close_handle = true;
+       }
+
+       bool const is_outpipe = index >= MAX_CLIENTS;
+
+       if (close_handle) {
+               DWORD const open_mode = is_outpipe ? PIPE_ACCESS_OUTBOUND
+                                                  : PIPE_ACCESS_INBOUND;
+               string const name = external_path(pipeName(index));
+
+               CloseHandle(pipe_[index].handle);
+
+               pipe_[index].iobuf.erase();
+               pipe_[index].handle = CreateNamedPipe(name.c_str(),
+                               open_mode | FILE_FLAG_OVERLAPPED, PIPE_WAIT,
+                               MAX_CLIENTS, PIPE_BUFSIZE, PIPE_BUFSIZE,
+                               PIPE_TIMEOUT, NULL);
+
+               if (pipe_[index].handle == INVALID_HANDLE_VALUE) {
+                       DWORD const error = GetLastError();
+                       lyxerr << "LyXComm: Could not reset pipe " << name
+                              << "\nLyXComm: " << errormsg(error) << endl;
+                       return false;
+               }
+       }
+
+       if (!startPipe(index))
+               return false;
+       pipe_[index].state = pipe_[index].pending_io ?
+                       CONNECTING_STATE : (is_outpipe ? WRITING_STATE
+                                                      : READING_STATE);
+       return true;
+}
+
+
+void LyXComm::openConnection()
+{
+       LYXERR(Debug::LYXSERVER, "LyXComm: Opening connection");
+
+       // If we are up, that's an error
+       if (ready_) {
+               LYXERR(Debug::LYXSERVER, "LyXComm: Already connected");
+               return;
+       }
+
+       if (pipename_.empty()) {
+               LYXERR(Debug::LYXSERVER, "LyXComm: server is disabled, nothing 
to do");
+               return;
+       }
+
+       // Check whether the pipe name is being used by some other program.
+       if (!stopserver_ && WaitNamedPipe(inPipeName().c_str(), 0)) {
+               lyxerr << "LyXComm: Pipe " << external_path(inPipeName())
+                      << " already exists.\nMaybe another instance of LyX"
+                         " is using it." << endl;
+               pipename_.erase();
+               return;
+       }
+
+       // Mutex with no initial owner for synchronized access to outbuf_
+       outbuf_mutex_ = CreateMutex(NULL, FALSE, NULL);
+       if (!outbuf_mutex_) {
+               DWORD const error = GetLastError();
+               lyxerr << "LyXComm: Could not create output buffer mutex"
+                      << "\nLyXComm: " << errormsg(error) << endl;
+               pipename_.erase();
+               return;
+       }
+
+       // Manual-reset event, initial state = not signaled
+       stopserver_ = CreateEvent(NULL, TRUE, FALSE, NULL);
+       if (!stopserver_) {
+               DWORD const error = GetLastError();
+               lyxerr << "LyXComm: Could not create stop server event"
+                      << "\nLyXComm: " << errormsg(error) << endl;
+               pipename_.erase();
+               CloseHandle(outbuf_mutex_);
+               return;
+       }
+
+       server_thread_ = CreateThread(NULL, 0, pipeServerWrapper,
+                                    static_cast<void *>(this), 0, NULL);
+       if (!server_thread_) {
+               DWORD const error = GetLastError();
+               lyxerr << "LyXComm: Could not create pipe server thread"
+                      << "\nLyXComm: " << errormsg(error) << endl;
+               pipename_.erase();
+               CloseHandle(stopserver_);
+               CloseHandle(outbuf_mutex_);
+               return;
+       }
+}
+
+
+/// Close pipes
+void LyXComm::closeConnection()
+{
+       LYXERR(Debug::LYXSERVER, "LyXComm: Closing connection");
+
+       if (pipename_.empty()) {
+               LYXERR(Debug::LYXSERVER, "LyXComm: server is disabled, nothing 
to do");
+               return;
+       }
+
+       if (!ready_) {
+               LYXERR(Debug::LYXSERVER, "LyXComm: Already disconnected");
+               return;
+       }
+
+       SetEvent(stopserver_);
+       // Wait for the pipe server to finish
+       WaitForSingleObject(server_thread_, INFINITE);
+       CloseHandle(server_thread_);
+       ResetEvent(stopserver_);
+       CloseHandle(stopserver_);
+       CloseHandle(outbuf_mutex_);
+}
+
+
+void LyXComm::emergencyCleanup()
+{
+       if (ready_) {
+               SetEvent(stopserver_);
+               // Forcibly terminate the pipe server thread if it does
+               // not finish quickly.
+               if (WaitForSingleObject(server_thread_, 200) != WAIT_OBJECT_0) {
+                       TerminateThread(server_thread_, 0);
+                       ready_ = false;
+                       closeHandles();
+               }
+               CloseHandle(server_thread_);
+               ResetEvent(stopserver_);
+               CloseHandle(stopserver_);
+               CloseHandle(outbuf_mutex_);
+       }
+}
+
+
+void LyXComm::read_ready(DWORD inpipe)
+{
+       // Turn the pipe buffer into a C string
+       DWORD const nbytes = pipe_[inpipe].nbytes;
+       pipe_[inpipe].readbuf[nbytes] = '\0';
+
+       pipe_[inpipe].iobuf += rtrim(pipe_[inpipe].readbuf, "\r");
+
+       // Commit any commands read
+       while (pipe_[inpipe].iobuf.find('\n') != string::npos) {
+               // split() grabs the entire string if
+               // the delim /wasn't/ found. ?:-P
+               string cmd;
+               pipe_[inpipe].iobuf = split(pipe_[inpipe].iobuf, cmd, '\n');
+               cmd = rtrim(cmd, "\r");
+               LYXERR(Debug::LYXSERVER, "LyXComm: nbytes:" << nbytes
+                       << ", iobuf:" << pipe_[inpipe].iobuf
+                       << ", cmd:" << cmd);
+               if (!cmd.empty())
+                       clientcb_(client_, cmd);
+                       //\n or not \n?
+       }
+       // Signal that we are done.
+       pipe_[inpipe].nbytes = 0;
+}
+
+
+void LyXComm::send(string const & msg)
+{
+       if (msg.empty()) {
+               lyxerr << "LyXComm: Request to send empty string. Ignoring."
+                      << endl;
+               return;
+       }
+
+       LYXERR(Debug::LYXSERVER, "LyXComm: Sending '" << msg << '\'');
+
+       if (pipename_.empty())
+               return;
+
+       if (!ready_) {
+               lyxerr << "LyXComm: Pipes are closed. Could not send "
+                      << msg << endl;
+               return;
+       }
+
+       // Request ownership of the outbuf_mutex_
+       DWORD result = WaitForSingleObject(outbuf_mutex_, PIPE_TIMEOUT);
+
+       if (result == WAIT_OBJECT_0) {
+               // If a client doesn't care to read a reply (JabRef is one
+               // such client), the output buffer could grow without limit.
+               // So, we empty it when its size is larger than PIPE_BUFSIZE.
+               if (outbuf_.size() > PIPE_BUFSIZE)
+                       outbuf_.erase();
+               outbuf_ += msg;
+               ReleaseMutex(outbuf_mutex_);
+       } else {
+               // Something is fishy, better resetting the connection.
+               DWORD const error = GetLastError();
+               lyxerr << "LyXComm: Error sending message: " << msg
+                      << "\nLyXComm: " << errormsg(error)
+                      << "\nLyXComm: Resetting connection" << endl;
+               ReleaseMutex(outbuf_mutex_);
+               closeConnection();
+               openConnection();
+       }
+}
+
+
+string const LyXComm::pipeName(DWORD index) const
+{
+       return index < MAX_CLIENTS ? inPipeName() : outPipeName();
+}
+
+
+#elif !defined (HAVE_MKFIFO)
 // We provide a stub class that disables the lyxserver.
 
 LyXComm::LyXComm(string const &, Server *, ClientCallbackfct)
@@ -537,3 +1145,7 @@ void Server::notifyClient(string const &
 
 
 } // namespace lyx
+
+#ifdef _WIN32
+#include "Server_moc.cpp"
+#endif
Index: src/Server.h
===================================================================
--- src/Server.h        (revision 31369)
+++ src/Server.h        (working copy)
@@ -6,6 +6,7 @@
  *
  * \author Lars Gullik Bjønnes
  * \author Jean-Marc Lasgouttes
+ * \author Enrico Forestieri
  *
  * Full author contact details are available in file CREDITS.
  */
@@ -15,6 +16,12 @@
 
 #include <boost/signals/trackable.hpp>
 
+#ifdef _WIN32
+#include <windows.h>
+#include <QObject>
+#include <QEvent>
+#endif
+
 
 namespace lyx {
 
@@ -29,7 +36,46 @@ class Server;
  This class encapsulates all the dirty communication and thus provides
  a clean string interface.
  */
+#ifndef _WIN32
 class LyXComm : public boost::signals::trackable {
+#else
+class LyXComm : public QObject {
+       Q_OBJECT
+
+       friend DWORD WINAPI pipeServerWrapper(void *);
+
+public:
+       /// Max number of clients
+       enum { MAX_CLIENTS = 10 };
+
+private:
+       /// Max number of pipe instances
+       enum { MAX_PIPES = 2 * MAX_CLIENTS };
+
+       /// I/O buffer size
+       enum { PIPE_BUFSIZE = 512 };
+
+       /// Pipe client time-out
+       enum { PIPE_TIMEOUT = 5000 };
+
+       /// Pipe states
+       enum PipeState {
+               CONNECTING_STATE,
+               READING_STATE,
+               WRITING_STATE
+       };
+
+       /// Pipe instances
+       typedef struct {
+               OVERLAPPED overlap;
+               HANDLE handle;
+               std::string iobuf;
+               char readbuf[PIPE_BUFSIZE];
+               DWORD nbytes;
+               PipeState state;
+               bool pending_io;
+       } PipeInst;
+#endif
 public:
        /** When we receive a message, we send it to a client.
          This is one of the small things that would have been a lot
@@ -50,7 +96,11 @@ public:
        void send(std::string const &);
 
        /// asynch ready-to-be-read notification
+#ifndef _WIN32
        void read_ready();
+#else
+       void read_ready(DWORD);
+#endif
 
 private:
        /// the filename of the in pipe
@@ -65,6 +115,7 @@ private:
        /// Close pipes
        void closeConnection();
 
+#ifndef _WIN32
        /// start a pipe
        int startPipe(std::string const &, bool);
 
@@ -76,6 +127,46 @@ private:
 
        /// This is -1 if not open
        int outfd_;
+#else
+       /// The pipe server returns false when exiting due to an error
+       bool pipeServer();
+
+       /// Start an overlapped connection
+       bool startPipe(DWORD);
+
+       /// Reset an overlapped connection
+       bool resetPipe(DWORD, bool close_handle = false);
+
+       /// Close event and pipe handles
+       void closeHandles();
+
+       /// Catch pipe ready-to-be-read notification
+       bool event(QEvent *);
+
+       /// Check whether the pipe server must be stopped
+       bool checkStopServer(DWORD timeout = 0);
+
+       /// The filename of a (in or out) pipe instance
+       std::string const pipeName(DWORD) const;
+
+       /// Pipe instances
+       PipeInst pipe_[MAX_PIPES];
+
+       /// Pipe server control events
+       HANDLE event_[MAX_PIPES + 1];
+
+       /// Reply buffer
+       std::string outbuf_;
+
+       /// Synchronize access to outbuf_
+       HANDLE outbuf_mutex_;
+
+       /// Windows event for stopping the pipe server
+       HANDLE stopserver_;
+
+       /// Pipe server thread handle
+       HANDLE server_thread_;
+#endif
 
        /// Are we up and running?
        bool ready_;
@@ -118,7 +209,11 @@ public:
 
 private:
        /// Names and number of current clients
+#ifndef _WIN32
        enum { MAX_CLIENTS = 10 };
+#else
+       enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS };
+#endif
        ///
        std::string clients_[MAX_CLIENTS];
        ///
Index: development/cmake/src/CMakeLists.txt
===================================================================
--- development/cmake/src/CMakeLists.txt        (revision 31369)
+++ development/cmake/src/CMakeLists.txt        (working copy)
@@ -34,8 +34,10 @@ if (ASPELL_FOUND)
        set(lyx_sources ${lyx_sources} ${TOP_SRC_DIR}/src/ASpell.cpp)
 endif()
 
+lyx_automoc(${TOP_SRC_DIR}/src/Server.cpp)
+
 include_directories(${CMAKE_CURRENT_BINARY_DIR}
-       ${ZLIB_INCLUDE_DIR})
+       ${ZLIB_INCLUDE_DIR} ${QT_INCLUDES})
 
 lyx_add_msvc_pch(lyx)
 
Index: development/cmake/modules/LyXMacros.cmake
===================================================================
--- development/cmake/modules/LyXMacros.cmake   (revision 31369)
+++ development/cmake/modules/LyXMacros.cmake   (working copy)
@@ -105,9 +105,12 @@ macro(LYX_AUTOMOC)
 
                set(_moc  ${CMAKE_CURRENT_BINARY_DIR}/${_current_MOC})
                #set(_moc ${_abs_PATH}/${_current_MOC})
+               if (WIN32)
+                       set(_def -D_WIN32)
+               endif()
                add_custom_command(OUTPUT ${_moc}
                        COMMAND ${QT_MOC_EXECUTABLE}
-                       ARGS ${_moc_INCS} ${_header} -o ${_moc}
+                       ARGS ${_def} ${_moc_INCS} ${_header} -o ${_moc}
                        MAIN_DEPENDENCY ${_header})
                macro_add_file_dependencies(${_abs_FILE} ${_moc})
             endforeach (_current_MOC_INC)
Index: development/scons/SConstruct
===================================================================
--- development/scons/SConstruct        (revision 31369)
+++ development/scons/SConstruct        (working copy)
@@ -903,6 +903,7 @@ result = utils.createConfigFile(conf,
         ('locale.h', 'HAVE_LOCALE_H', 'c'),
         ('process.h', 'HAVE_PROCESS_H', 'c'),
         ('stdlib.h', 'HAVE_STDLIB_H', 'c'),
+        ('string.h', 'HAVE_STRING_H', 'c'),
         ('sys/stat.h', 'HAVE_SYS_STAT_H', 'c'),
         ('sys/time.h', 'HAVE_SYS_TIME_H', 'c'),
         ('sys/types.h', 'HAVE_SYS_TYPES_H', 'c'),
@@ -1287,30 +1288,29 @@ if platform_name == 'cygwin':
 # to be built with all the include directories etc
 #
 if frontend == 'qt4':
-    frontend_env = env.Clone()
-    frontend_env['BUILDERS']['qtResource'] = Builder(action = 
utils.env_qtResource)
+    env['BUILDERS']['qtResource'] = Builder(action = utils.env_qtResource)
 
     # handle qt related user specified paths
     # set environment so that moc etc can be found even if its path is not set 
properly
-    if frontend_env.has_key('qt_dir') and frontend_env['qt_dir']:
-        frontend_env['QTDIR'] = frontend_env['qt_dir']
-        if os.path.isdir(os.path.join(frontend_env['qt_dir'], 'bin')):
-            os.environ['PATH'] += os.pathsep + 
os.path.join(frontend_env['qt_dir'], 'bin')
-            frontend_env.PrependENVPath('PATH', 
os.path.join(frontend_env['qt_dir'], 'bin'))
-        if os.path.isdir(os.path.join(frontend_env['qt_dir'], 'lib')):
-            frontend_env.PrependENVPath('PKG_CONFIG_PATH', 
os.path.join(frontend_env['qt_dir'], 'lib'))
+    if env.has_key('qt_dir') and env['qt_dir']:
+        env['QTDIR'] = env['qt_dir']
+        if os.path.isdir(os.path.join(env['qt_dir'], 'bin')):
+            os.environ['PATH'] += os.pathsep + os.path.join(env['qt_dir'], 
'bin')
+            env.PrependENVPath('PATH', os.path.join(env['qt_dir'], 'bin'))
+        if os.path.isdir(os.path.join(env['qt_dir'], 'lib')):
+            env.PrependENVPath('PKG_CONFIG_PATH', os.path.join(env['qt_dir'], 
'lib'))
 
     # if separate qt_lib_path is given
-    if frontend_env.has_key('qt_lib_path') and frontend_env['qt_lib_path']:
-        qt_lib_path = frontend_env.subst('$qt_lib_path')
-        frontend_env.AppendUnique(LIBPATH = [qt_lib_path])
-        frontend_env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
+    if env.has_key('qt_lib_path') and env['qt_lib_path']:
+        qt_lib_path = env.subst('$qt_lib_path')
+        env.AppendUnique(LIBPATH = [qt_lib_path])
+        env.PrependENVPath('PKG_CONFIG_PATH', qt_lib_path)
     else:
         qt_lib_path = None
 
     # if separate qt_inc_path is given
-    if frontend_env.has_key('qt_inc_path') and frontend_env['qt_inc_path']:
-        qt_inc_path = frontend_env['qt_inc_path']
+    if env.has_key('qt_inc_path') and env['qt_inc_path']:
+        qt_inc_path = env['qt_inc_path']
     else:
         qt_inc_path = None
 
@@ -1320,18 +1320,20 @@ if frontend == 'qt4':
     # NOTE: I have to patch qt4.py since it does not automatically
     # process .C file!!! (add to cxx_suffixes )
     #
-    frontend_env.Tool('qt4', [scons_dir])
-    frontend_env['QT_AUTOSCAN'] = 0
-    frontend_env['QT4_AUTOSCAN'] = 0
-    frontend_env['QT4_UICDECLFLAGS'] = '-tr lyx::qt_'
+    env.Tool('qt4', [scons_dir])
+    env['QT_AUTOSCAN'] = 0
+    env['QT4_AUTOSCAN'] = 0
+    env['QT4_UICDECLFLAGS'] = '-tr lyx::qt_'
+    if platform_name == 'win32':
+        env['QT4_MOCFROMHFLAGS'] = '-D_WIN32'
 
     if qt_lib_path is None:
-        qt_lib_path = os.path.join(frontend_env.subst('$QTDIR'), 'lib')
+        qt_lib_path = os.path.join(env.subst('$QTDIR'), 'lib')
     if qt_inc_path is None:
-        qt_inc_path = os.path.join(frontend_env.subst('$QTDIR'), 'include')
+        qt_inc_path = os.path.join(env.subst('$QTDIR'), 'include')
 
 
-    conf = Configure(frontend_env,
+    conf = Configure(env,
         custom_tests = { 
             'CheckPackage' : utils.checkPackage,
             'CheckCommand' : utils.checkCommand,
@@ -1340,10 +1342,10 @@ if frontend == 'qt4':
 
     succ = False
     # first: try pkg_config
-    if frontend_env['HAS_PKG_CONFIG']:
+    if env['HAS_PKG_CONFIG']:
         succ = conf.CheckPackage('QtCore') or conf.CheckPackage('QtCore4')
         # FIXME: use pkg_config information?
-        #frontend_env['QT4_PKG_CONFIG'] = succ
+        #env['QT4_PKG_CONFIG'] = succ
     # second: try to link to it
     if not succ:
         # Under linux, I can test the following perfectly
@@ -1375,7 +1377,7 @@ if frontend == 'qt4':
         else:
             qt_lib_suffix = ''
             use_qt_debug_libs = False
-    frontend_env.EnableQt4Modules(qt_libs, debug = (mode == 'debug' and 
use_qt_debug_libs))
+    env.EnableQt4Modules(qt_libs, debug = (mode == 'debug' and 
use_qt_debug_libs))
     frontend_libs = [x + qt_lib_suffix for x in qt_libs]
     qtcore_lib = ['QtCore' + qt_lib_suffix]
 
@@ -1388,11 +1390,11 @@ if frontend == 'qt4':
     # NOTE: previously, lyx.exe had to be linked to some qt manifest to work.
     # For some unknown changes in msvc or qt, this is no longer needed.
     if use_vc:
-        frontend_env['LINKCOM'] = [frontend_env['LINKCOM'], \
+        env['LINKCOM'] = [env['LINKCOM'], \
             'mt.exe /MANIFEST %s /outputresource:$TARGET;1' % \
             env.File('$BUILDDIR/lyx.exe.manifest').path]
 
-    frontend_env = conf.Finish()
+    env = conf.Finish()
 
 #
 # Report results
@@ -1435,7 +1437,7 @@ env.SConsignFile(os.path.join(Dir(env['B
 env.BuildDir('$BUILDDIR/boost', '$TOP_SRCDIR/boost/libs', duplicate = 0)
 env.BuildDir('$BUILDDIR/intl', '$TOP_SRCDIR/intl', duplicate = 0)
 env.BuildDir('$BUILDDIR/src', '$TOP_SRCDIR/src', duplicate = 0)
-frontend_env.BuildDir('$BUILDDIR/src', '$TOP_SRCDIR/src', duplicate = 0)
+env.BuildDir('$BUILDDIR/src', '$TOP_SRCDIR/src', duplicate = 0)
 
 print "Building all targets recursively"
 
@@ -1493,12 +1495,12 @@ if (included_gettext and not libExists('
 #
 # src/support
 #
-frontend_env['QT4_MOCHPREFIX'] = ''
-frontend_env['QT4_MOCHSUFFIX'] = '_moc.cpp'
+env['QT4_MOCHPREFIX'] = ''
+env['QT4_MOCHSUFFIX'] = '_moc.cpp'
 
-support_moced_files = [frontend_env.Moc4('$BUILDDIR/src/support/%s' % x)
+support_moced_files = [env.Moc4('$BUILDDIR/src/support/%s' % x)
     for x in src_support_header_files ]
-support = frontend_env.StaticLibrary(
+support = env.StaticLibrary(
     target = '$LOCALLIBPATH/support',
     source = ['$BUILDDIR/src/support/%s' % x for x in src_support_files],
     CCFLAGS =  [
@@ -1511,97 +1513,18 @@ support = frontend_env.StaticLibrary(
 )
 Alias('support', support)
 
-
-#
-# src/mathed
-#
-mathed = env.StaticLibrary(
-    target = '$LOCALLIBPATH/mathed',
-    source = ['$BUILDDIR/src/mathed/%s' % x for x in src_mathed_files]
-)
-Alias('mathed', mathed)
-
-
-#
-# src/insets
-#
-insets = env.StaticLibrary(
-    target = '$LOCALLIBPATH/insets',
-    source = ['$BUILDDIR/src/insets/%s' % x for x in src_insets_files]
-)
-Alias('insets', insets)
-
-
-#
-# src/frontends
-#
-frontends = env.StaticLibrary(
-    target = '$LOCALLIBPATH/frontends',
-    source = ['$BUILDDIR/src/frontends/%s' % x for x in src_frontends_files]
-)
-Alias('frontends', frontends)
-
-
-#
-# src/graphics
-#
-graphics = env.StaticLibrary(
-    target = '$LOCALLIBPATH/graphics',
-    source = ['$BUILDDIR/src/graphics/%s' % x for x in src_graphics_files]
-)
-Alias('graphics', graphics)
-
-
-#
-# src/frontend/qt4
-#
-# tells scons how to get these moced files, although not all moced files are 
needed
-# (or are actually generated).
-qt4_moced_files = [frontend_env.Moc4('$BUILDDIR/src/frontends/qt4/%s' % x)
-    for x in src_frontends_qt4_header_files ]
-ui_files = [frontend_env.Uic4('$BUILDDIR/src/frontends/qt4/ui/%s' % 
x.split('.')[0])
-    for x in src_frontends_qt4_ui_files]
-resource = frontend_env.Qrc(frontend_env.qtResource(
-    '$BUILDDIR/src/frontends/qt4/Resource.qrc',
-    ['$TOP_SRCDIR/lib/images/%s' % x for x in lib_images_files] +
-    ['$TOP_SRCDIR/lib/images/math/%s' % x for x in lib_images_math_files] +
-    ['$TOP_SRCDIR/lib/images/commands/%s' % x for x in 
lib_images_commands_files]))
-#
-# moc qt4_moc_files, the moced files are included in the original files
-#
-qt4 = frontend_env.StaticLibrary(
-    target = '$LOCALLIBPATH/qt4',
-    source = ['$BUILDDIR/src/frontends/qt4/%s' % x for x in 
src_frontends_qt4_files] + resource,
-    CPPPATH = [
-        '$CPPPATH',
-        '$BUILDDIR/src',
-        '$BUILDDIR/src/images',
-        '$BUILDDIR/src/frontends',
-        '$BUILDDIR/src/frontends/qt4',
-        '$BUILDDIR/src/frontends/qt4/ui',
-    ],
-    CCFLAGS =  [
-        '$CCFLAGS',
-        '-DHAVE_CONFIG_H',
-        '-DQT_NO_STL',
-        '-DQT_NO_KEYWORDS',
-    ]
-)
-Alias('qt4', qt4)
-
-
 #
-# src/client
+# lyxclient
 #
 if env['HAVE_FCNTL']:
-    client = frontend_env.Program(
+    client = env.Program(
         target = '$BUILDDIR/src/client/lyxclient',
         LIBS = ['support'] + intl_libs + system_libs +
             socket_libs + boost_libraries + qtcore_lib,
         source = ['$BUILDDIR/src/client/%s' % x for x in src_client_files] + \
-            utils.createResFromIcon(frontend_env, 'lyx.ico', 
'$LOCALLIBPATH/client.rc')
+            utils.createResFromIcon(env, 'lyx.ico', '$LOCALLIBPATH/client.rc')
     )
-    Alias('client', frontend_env.Command(os.path.join('$BUILDDIR', 
os.path.split(str(client[0]))[1]),
+    Alias('client', env.Command(os.path.join('$BUILDDIR', 
os.path.split(str(client[0]))[1]),
         client, [Copy('$TARGET', '$SOURCE')]))
 else:
     client = None
@@ -1612,25 +1535,25 @@ Alias('client', client)
 # tex2lyx
 #
 for file in src_tex2lyx_copied_files + src_tex2lyx_copied_header_files:
-    frontend_env.Command('$BUILDDIR/src/tex2lyx/'+file, 
'$TOP_SRCDIR/src/'+file,
+    env.Command('$BUILDDIR/src/tex2lyx/'+file, '$TOP_SRCDIR/src/'+file,
         [Copy('$TARGET', '$SOURCE')])
 
-tex2lyx = frontend_env.Program(
+tex2lyx = env.Program(
     target = '$BUILDDIR/src/tex2lyx/tex2lyx',
     LIBS = ['support'] + boost_libraries + intl_libs + system_libs + 
qtcore_lib,
     source = ['$BUILDDIR/src/tex2lyx/%s' % x for x in src_tex2lyx_files + 
src_tex2lyx_copied_files] + \
-        utils.createResFromIcon(frontend_env, 'lyx.ico', 
'$LOCALLIBPATH/tex2lyx.rc'),
+        utils.createResFromIcon(env, 'lyx.ico', '$LOCALLIBPATH/tex2lyx.rc'),
     CPPPATH = ['$BUILDDIR/src/tex2lyx', '$BUILDDIR/src', '$CPPPATH'],
     LIBPATH = ['#$LOCALLIBPATH', '$LIBPATH'],
     CCFLAGS = ['$CCFLAGS', '-DTEX2LYX'],
 )
-Alias('tex2lyx', frontend_env.Command(os.path.join('$BUILDDIR', 
os.path.split(str(tex2lyx[0]))[1]),
+Alias('tex2lyx', env.Command(os.path.join('$BUILDDIR', 
os.path.split(str(tex2lyx[0]))[1]),
     tex2lyx, [Copy('$TARGET', '$SOURCE')]))
 Alias('tex2lyx', tex2lyx)
 
 
 #
-# src/
+# Build lyx with given frontend
 #
 if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
     src_post_files.append('ASpell.cpp')
@@ -1639,37 +1562,50 @@ elif env.has_key('USE_PSPELL') and env['
 elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
     src_post_files.append('ISpell.cpp')
 
-# msvc requires at least one source file with main()
-# so I exclude main.cpp from lyxbase
-lyxbase_pre = env.StaticLibrary(
-    target = '$LOCALLIBPATH/lyxbase_pre',
-    source = ['$BUILDDIR/src/%s' % x for x in src_pre_files]
-)
-lyxbase_post = env.StaticLibrary(
-    target = '$LOCALLIBPATH/lyxbase_post',
-    source = ["$BUILDDIR/src/%s" % x for x in src_post_files]
-)
-Alias('lyxbase', lyxbase_pre)
-Alias('lyxbase', lyxbase_post)
-
+# tells scons how to get these moced files, although not all moced files are 
needed
+# (or are actually generated).
+qt4_moced_files = [env.Moc4('$BUILDDIR/src/frontends/qt4/%s' % x)
+    for x in src_frontends_qt4_header_files ]
+src_moced_files = [env.Moc4('$BUILDDIR/src/%s' % x)
+    for x in src_header_files ]
+ui_files = [env.Uic4('$BUILDDIR/src/frontends/qt4/ui/%s' % x.split('.')[0])
+    for x in src_frontends_qt4_ui_files]
+resource = env.Qrc(env.qtResource(
+    '$BUILDDIR/src/frontends/qt4/Resource.qrc',
+    ['$TOP_SRCDIR/lib/images/%s' % x for x in lib_images_files] +
+    ['$TOP_SRCDIR/lib/images/math/%s' % x for x in lib_images_math_files] +
+    ['$TOP_SRCDIR/lib/images/commands/%s' % x for x in 
lib_images_commands_files]))
 
-#
-# Build lyx with given frontend
-#
-lyx = frontend_env.Program(
+lyx = env.Program(
     target = '$BUILDDIR/lyx',
-    source = ['$BUILDDIR/src/main.cpp'] + \
-        utils.createResFromIcon(frontend_env, 'lyx.ico', 
'$LOCALLIBPATH/lyx.rc'),
+    source = ['$BUILDDIR/src/main.cpp'] +
+       ['$BUILDDIR/src/frontends/qt4/%s' % x for x in src_frontends_qt4_files] 
+
+       resource +
+       ['$BUILDDIR/src/graphics/%s' % x for x in src_graphics_files] +
+       ['$BUILDDIR/src/mathed/%s' % x for x in src_mathed_files] +
+       ['$BUILDDIR/src/insets/%s' % x for x in src_insets_files] +
+       ['$BUILDDIR/src/frontends/%s' % x for x in src_frontends_files] +
+       ['$BUILDDIR/src/%s' % x for x in src_pre_files] +
+       ["$BUILDDIR/src/%s" % x for x in src_post_files] +
+        utils.createResFromIcon(env, 'lyx.ico', '$LOCALLIBPATH/lyx.rc'),
+    CPPPATH = [
+        '$CPPPATH',
+        '$BUILDDIR/src',
+        '$BUILDDIR/src/images',
+        '$BUILDDIR/src/frontends',
+        '$BUILDDIR/src/frontends/qt4',
+        '$BUILDDIR/src/frontends/qt4/ui',
+    ],
+    CCFLAGS =  [
+        '$CCFLAGS',
+        '-DHAVE_CONFIG_H',
+        '-DQT_NO_STL',
+        '-DQT_NO_KEYWORDS',
+    ],
     LIBS = [
-        'lyxbase_pre',
-        'mathed',
-        'insets',
-        'frontends',
-        frontend,
-        'graphics',
         'support',
         ] +
-        boost_libraries + ['lyxbase_post'] +
+        boost_libraries + 
         frontend_libs +
         intl_libs +
         socket_libs +
Index: config/lyxinclude.m4
===================================================================
--- config/lyxinclude.m4        (revision 31369)
+++ config/lyxinclude.m4        (working copy)
@@ -610,6 +610,7 @@ AC_ARG_WITH(packaging,
 AC_MSG_RESULT($lyx_use_packaging)
 lyx_install_macosx=false
 lyx_install_cygwin=false
+lyx_install_windows=false
 case $lyx_use_packaging in
    macosx) AC_DEFINE(USE_MACOSX_PACKAGING, 1, [Define to 1 if LyX should use a 
MacOS X application bundle file layout])
           PACKAGE=LyX${version_suffix}
@@ -627,7 +628,8 @@ case $lyx_use_packaging in
           libdir='${prefix}/Resources'
           datarootdir='${prefix}/Resources'
           pkgdatadir='${datadir}'
-          mandir='${prefix}/Resources/man' ;;
+          mandir='${prefix}/Resources/man'
+          lyx_install_windows=true ;;
     posix) AC_DEFINE(USE_POSIX_PACKAGING, 1, [Define to 1 if LyX should use a 
POSIX-style file layout])
           PACKAGE=lyx${version_suffix}
           program_suffix=$version_suffix
@@ -640,6 +642,7 @@ case $lyx_use_packaging in
 esac
 AM_CONDITIONAL(INSTALL_MACOSX, $lyx_install_macosx)
 AM_CONDITIONAL(INSTALL_CYGWIN, $lyx_install_cygwin)
+AM_CONDITIONAL(INSTALL_WINDOWS, $lyx_install_windows)
 dnl Next two lines are only for autoconf <= 2.59
 datadir='${datarootdir}'
 AC_SUBST(datarootdir)

Reply via email to