#645 Support compiling the Qt terminal on Windows

Thomas Bleher

The attached patch makes it possible to compile the Qt terminal on Windows (using MSVC).
Unfortunately, the gnuplot terminal does not yet work correctly on Windows. The reason: select() is too limited on Windows. qt_waitforinput() uses select() to simultaneously wait on stdin and on a named pipe.

On Windows, select can only be used to wait on network sockets. There is WaitForMultipleObjects(), but I couldn't get it to work that way (probably because the QLocalSocket is already registered inside the Qt event loop). So this is no complete solution, but it is a starting point.

I would welcome if the patch could be included, even if the Qt terminal does not yet work on Windows:
- It makes it easier for someone else to continue this work
- It is disabled by default, so other people building on Windows won't be impacted
- All the new code is #defined so it only runs on Windows. So non-Windows-builds will continue to work (I tested this on Linux)

Some more information about the changes inside the patch.

1 Attachments


  • Here is a patch of qt_term.cpp that might solve this problem. It changes all non-portable system calls to Qt equivalents, which are supposed to be cross-platform:
    - fork() and execlv() are replaced by a QProcess
    - select() is replaced by a QEventLoop

    I tested it on Linux.

    Besides, concerning your original patch, I don't understand why there is a need to modifiy gnuplot_qt.cpp. Can't MSVC compile and run the usual int main(int argc, char* argv[]) entry point ?

  • Thomas Bleher
    Thomas Bleher

    Unfortunately QSocketNotifier doesn't work on stdin on Windows, because stdin is not a socket on Windows (see https://bugreports.qt-project.org/browse/QTBUG-15457). I just tested your patch, and it hangs in the call to qt-eventLoop.exec(), after the first plot command has been sent.

    Look at ConsoleGetch() in src/win/winmain.c to see how much code is needed on Windows to wait for a character input and simultaneously wait for GUI event. I fear similar code would be needed in qt_term.cpp, with a MsgWaitForMultipleInput that waits both for stdin and for the socket. I already tried to do this, but it didn't work correctly.

    You are right that MSVC supports a main-function, but it needs an extra linker flag when creating a GUI application (versus a console application). I didn't know that when I wrote the patch.

    Attached is a new patch against current CVS that adds the correct linker flag to the MSVC makefile. It would be nice to have this added to CVS, as it doesn't impact current code, and makes future experimentation with Qt on Windows much easier.

  • Ethan Merritt
    Ethan Merritt

    The patch switching to QEventLoop causes problems under linux as well. In particular it fails to deal with ctrl-C used to interrupt execution of a "load" command.

    gnuplot> load 'iterate.dem'
    Hit return to continue^C
    gnuplot> QEventLoop::exec: instance 0x9729064 has already called exec()

    gnuplot> QEventLoop::exec: instance 0x9729064 has already called exec()

    At this point the program is wedged and must be killed externally. I imagine this is fixable, but if the patch does not help with Windows compatibility anyway then I don't see much reason to pursue it.

  • Here is another attempt. With this patch, a thread is started to watch standard input and forward its content to the main thread using a QLocalSocket. It still has rough edges (initialization sometimes fails, and there is uncleaned stuff at exit), but it could be a start.

  • The attached patch makes the qt terminal "work" in wgnuplot. The waitforinput routine alternates between "polling" the LocalSocket and the Windows Message Queue. This isn't nice, but works reasonably. In order to make key commands working, I included Thomas' recursion patch

    As Thomas already pointed out, the LocalSocket is really implemented using a named pipe on Windows and thus selecting isn't allowed.

    The patch also includes the Windows variant of Ethan's analysis concerning the connection problem to gnuplot_qt, which solves these problems at least on my system.

    Tested using MSVC 2012 and Qt 5.2.1.

  • Ethan Merritt
    Ethan Merritt

    Doesn't configuration with MSVC define HAVE_SELECT? I thought it did have select but didn't support it for pipes/streams. So does your HAVE_SELECT conditional code section get compiled on Windows or not?

    Next thing:
    I have found another rather alarming statement in the Qt docs. It states that if the waitForConnected(timeout) timeout ever triggers, it will terminate the process being waited for. That's really strange, but whatever. So we shouldn't have a timeout there at all. I will modify that loop in CVS.

    This patch:
    I'm OK with this patch, modulo my question above, but I'm a bit unclear how many of the other modifications mentioned here and on the mailing list are needed with it. Does it sit on top of, or replace, Jérôme's threaded_stdin patch attached above? I haven't looked at that one yet.

  • MSVC or MinGW do indeed have select(), but HAVE_SELECT is typically not defined in config.nt nor config.mgw. But WIN32 would be the better coice indeed, since the select() code cannot work on Windows.

    In the meantime I have come up with a more elegant solution than the previous polling attempt. The attached patch uses the Windows equivalent of select -- MsgWaitForMultipleObjects -- to wait for stdin, console, qt pipe, or message queue events. It supports both, console mode gnuplot and wgnuplot. No further patches are required.

    I will upload a testing binary to http://www.gnuplot.info/development/binaries/ .

  • The qt terminal more or less works now on Windows. It still has a few issues, though. While e.g. rotating 3d graphs with the mouse is fast as lightning (Wow, that is impressive!), some plots take ages to appear (e.g. the last three plots in random.dem).

    • Ethan Merritt
      Ethan Merritt

      If you replot, or save and load, one of the slow plots is it still slow?
      If not maybe this is some side effect of the demo script it is wrapped in.

      • You are right. Doing a clear followed by replot is indeed fast. This problem does not show up with the windows or wxt terminals btw.

        • Got it. This is caused by the timeout (currently 50 ms) in qt_waitforinput(TERM_ONLY_CHECK_MOUSING) calls.

    • labels: --> Windows
    • labels: Windows --> Windows, qt
    • status: open --> closed-accepted