summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openscad.pro5
-rw-r--r--scripts/installer.nsi1
-rwxr-xr-xscripts/release-common.sh9
-rw-r--r--src/winconsole.c146
-rw-r--r--winconsole.pri28
5 files changed, 189 insertions, 0 deletions
diff --git a/openscad.pro b/openscad.pro
index b11f45b..a7088ec 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -344,3 +344,8 @@ INSTALLS += applications
icons.path = $$PREFIX/share/pixmaps
icons.files = icons/openscad.png
INSTALLS += icons
+
+CONFIG(winconsole) {
+ include(winconsole.pri)
+}
+
diff --git a/scripts/installer.nsi b/scripts/installer.nsi
index 87ec18d..1841431 100644
--- a/scripts/installer.nsi
+++ b/scripts/installer.nsi
@@ -6,6 +6,7 @@ DirText "This will install OpenSCAD on your computer. Choose a directory"
Section "install"
SetOutPath $INSTDIR
File openscad.exe
+File openscad.com
File /r /x mingw-cross-env examples
File /r /x mingw-cross-env libraries
${registerExtension} "$INSTDIR\openscad.exe" ".scad" "OpenSCAD_File"
diff --git a/scripts/release-common.sh b/scripts/release-common.sh
index ae856df..de14cb1 100755
--- a/scripts/release-common.sh
+++ b/scripts/release-common.sh
@@ -166,7 +166,14 @@ fi
case $OS in
LINXWIN)
# dont use paralell builds, it can error-out on parser_yacc.
+
+ # make main openscad.exe
cd $DEPLOYDIR && make $TARGET
+
+ # make console pipe-able openscad.com - see winconsole.pri for info
+ i686-pc-mingw32-qmake CONFIG+=winconsole ../openscad.pro
+ make
+
cd $OPENSCADDIR
;;
*)
@@ -232,6 +239,7 @@ case $OS in
#package
cp win32deps/* openscad-$VERSION
cp $TARGET/openscad.exe openscad-$VERSION
+ cp $TARGET/openscad.com openscad-$VERSION
rm -f openscad-$VERSION.zip
"$ZIP" $ZIPARGS openscad-$VERSION.zip openscad-$VERSION
rm -rf openscad-$VERSION
@@ -242,6 +250,7 @@ case $OS in
echo "Creating binary package"
cd $DEPLOYDIR
cp $TARGET/openscad.exe openscad-$VERSION
+ cp $TARGET/openscad.com openscad-$VERSION
rm -f OpenSCAD-$VERSION.zip
"$ZIP" $ZIPARGS OpenSCAD-$VERSION.zip openscad-$VERSION
cd $OPENSCADDIR
diff --git a/src/winconsole.c b/src/winconsole.c
new file mode 100644
index 0000000..2180e19
--- /dev/null
+++ b/src/winconsole.c
@@ -0,0 +1,146 @@
+// enable easy piping under windows command line, using the 'devenv' method
+// http://stackoverflow.com/questions/493536/can-one-executable-be-both-a-console-and-gui-app
+// http://blogs.msdn.com/b/oldnewthing/archive/2009/01/01/9259142.aspx
+// http://blogs.msdn.com/b/junfeng/archive/2004/02/06/68531.aspx
+// http://www.i18nguy.com/unicode/c-unicode.html
+
+/*
+
+Based on inkscapec by Jos Hirth work at http://kaioa.com
+and Nop Head's OpenSCAD_cl at github.com
+
+Zero-clause BSD-style license (DGAF)
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+void HandleOutput(HANDLE hPipeRead);
+DWORD WINAPI RedirThread(LPVOID lpvThreadParam);
+
+HANDLE hChildProcess=NULL;
+HANDLE hStdIn=NULL;
+BOOL bRunThread=TRUE;
+
+int main(int argc,char *argv[]){
+ HANDLE hOutputReadTemp,hOutputRead,hOutputWrite;
+ HANDLE hInputWriteTemp,hInputRead,hInputWrite;
+ HANDLE hErrorWrite;
+ HANDLE hThread;
+ DWORD ThreadId;
+ SECURITY_ATTRIBUTES sa;
+
+ sa.nLength=sizeof(SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor=NULL;
+ sa.bInheritHandle=TRUE;
+
+ int i;
+ wchar_t cmd[32000];
+ wcscat( cmd,L"\0" );
+ wcscat( cmd,L"openscad.exe" );
+ int wargc;
+ LPWSTR *wargv;
+ wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
+ if ( !wargv ) {
+ printf(" error in CommandLineToArgvW\n");
+ return 1;
+ }
+ for(i=1;i<argc;i++){
+ wcscat( cmd, L" " );
+ wcscat( cmd, wargv[i] );
+ }
+ LocalFree( wargv );
+
+ CreatePipe(&hOutputReadTemp,&hOutputWrite,&sa,0);
+ DuplicateHandle(GetCurrentProcess(),hOutputWrite,GetCurrentProcess(),&hErrorWrite,0,TRUE,DUPLICATE_SAME_ACCESS);
+ CreatePipe(&hInputRead,&hInputWriteTemp,&sa,0);
+ DuplicateHandle(GetCurrentProcess(),hOutputReadTemp,GetCurrentProcess(),&hOutputRead,0,FALSE,DUPLICATE_SAME_ACCESS);
+ DuplicateHandle(GetCurrentProcess(),hInputWriteTemp,GetCurrentProcess(),&hInputWrite,0,FALSE,DUPLICATE_SAME_ACCESS);
+ CloseHandle(hOutputReadTemp);
+ CloseHandle(hInputWriteTemp);
+
+ hStdIn=GetStdHandle(STD_INPUT_HANDLE);
+
+ //-
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+
+ ZeroMemory(&si,sizeof(STARTUPINFO));
+ si.cb=sizeof(STARTUPINFO);
+ si.dwFlags=STARTF_USESTDHANDLES;
+ si.hStdOutput=hOutputWrite;
+ si.hStdInput=hInputRead;
+ si.hStdError=hErrorWrite;
+
+ CreateProcess(NULL,cmd,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
+
+ hChildProcess=pi.hProcess;
+
+ CloseHandle(pi.hThread);
+ //-
+
+ CloseHandle(hOutputWrite);
+ CloseHandle(hInputRead);
+ CloseHandle(hErrorWrite);
+
+ hThread=CreateThread(NULL,0,RedirThread,(LPVOID)hInputWrite,0,&ThreadId);
+
+ HandleOutput(hOutputRead);
+
+ CloseHandle(hStdIn);
+
+ bRunThread=FALSE;
+
+ WaitForSingleObject(hThread,INFINITE);
+ CloseHandle(hOutputRead);
+ CloseHandle(hInputWrite);
+
+ return 0;
+}
+
+void HandleOutput(HANDLE hPipeRead){
+ CHAR lpBuffer[256];
+ DWORD nRead;
+ DWORD nWrote;
+
+ while(TRUE){
+ if(!ReadFile(hPipeRead,lpBuffer,sizeof(lpBuffer),&nRead,NULL)||!nRead)
+ if(GetLastError()==ERROR_BROKEN_PIPE)
+ break;
+ WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),lpBuffer,nRead,&nWrote,NULL);
+ }
+}
+
+DWORD WINAPI RedirThread(LPVOID lpvThreadParam){
+ CHAR buff[256];
+ DWORD nRead,nWrote;
+ HANDLE hPipeWrite=(HANDLE)lpvThreadParam;
+
+ while(bRunThread){
+ ReadConsole(hStdIn,buff,1,&nRead,NULL);
+
+ buff[nRead]='\0';
+
+ if(!WriteFile(hPipeWrite,buff,nRead,&nWrote,NULL)){
+ if(GetLastError()==ERROR_NO_DATA)
+ break;
+ }
+ }
+ return 1;
+}
diff --git a/winconsole.pri b/winconsole.pri
new file mode 100644
index 0000000..a3991ae
--- /dev/null
+++ b/winconsole.pri
@@ -0,0 +1,28 @@
+# Windows console issues workaround stub.
+#
+# Usage: put at the end of .pro file, then run qmake CONFIG+=winconsole
+#
+# This attempts to solve the problem of piping OpenSCAD under windows
+# command line (GUI mode programs in Windows dont allow this). We use
+# the 'devenv' solution, which means building two binaries:
+# openscad.exe, and openscad.com, the latter being a wrapper for the
+# former. See src/winconsole.c for more details.
+#
+# Qmake doesn't like building two binaries in the same directory so we
+# depend on release-common.sh to call qmake twice and package the file properly
+
+CONFIG(winconsole) {
+ TEMPLATE = app
+ TARGET = openscad_winconsole
+ FORMS =
+ HEADERS =
+ FLEXSOURCES =
+ BISONSOURCES =
+ RESOURCES =
+ SOURCES = src/winconsole.c
+ CONFIG += console # sets IMAGE_SUBSYSTEM_WINDOWS_CUI in binary
+ LIBS -= $$LIBS
+ RC_FILE -= $$RC_FILE
+ QMAKE_POST_LINK = cd $(DESTDIR) && mv openscad_winconsole.exe openscad.com
+}
+
contact: Jan Huwald // Impressum