summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h2
-rw-r--r--linux.c11
-rw-r--r--macos.c11
-rw-r--r--main.cpp6
-rw-r--r--subsurfacestartup.c5
-rw-r--r--windows.c77
6 files changed, 111 insertions, 1 deletions
diff --git a/dive.h b/dive.h
index dd321a7b9..701767b3a 100644
--- a/dive.h
+++ b/dive.h
@@ -720,6 +720,8 @@ extern FILE *subsurface_fopen(const char *path, const char *mode);
extern void *subsurface_opendir(const char *path);
extern struct zip *subsurface_zip_open_readonly(const char *path, int flags, int *errorp);
extern int subsurface_zip_close(struct zip *zip);
+extern void subsurface_console_init(bool dedicated);
+extern void subsurface_console_exit(void);
extern void shift_times(const timestamp_t amount);
extern timestamp_t get_times();
diff --git a/linux.c b/linux.c
index 6bfb38126..ea0170dc8 100644
--- a/linux.c
+++ b/linux.c
@@ -131,3 +131,14 @@ int subsurface_zip_close(struct zip *zip)
{
return zip_close(zip);
}
+
+/* win32 console */
+void subsurface_console_init(bool dedicated)
+{
+ /* NOP */
+}
+
+void subsurface_console_exit(void)
+{
+ /* NOP */
+}
diff --git a/macos.c b/macos.c
index 01c3fbfb5..19ce9e89d 100644
--- a/macos.c
+++ b/macos.c
@@ -112,3 +112,14 @@ int subsurface_zip_close(struct zip *zip)
{
return zip_close(zip);
}
+
+/* win32 console */
+void subsurface_console_init(bool dedicated)
+{
+ /* NOP */
+}
+
+void subsurface_console_exit(void)
+{
+ /* NOP */
+}
diff --git a/main.cpp b/main.cpp
index c93121400..a011b4caf 100644
--- a/main.cpp
+++ b/main.cpp
@@ -23,6 +23,11 @@ int main(int argc, char **argv)
QStringList files;
QStringList importedFiles;
QStringList arguments = QCoreApplication::arguments();
+
+ bool dedicated_console = arguments.length() > 1 &&
+ (arguments.at(1) == QString("--win32console"));
+ subsurface_console_init(dedicated_console);
+
for (i = 1; i < arguments.length(); i++) {
QString a = arguments.at(i);
if (a.at(0) == '-') {
@@ -56,5 +61,6 @@ int main(int argc, char **argv)
run_ui();
exit_ui();
parse_xml_exit();
+ subsurface_console_exit();
return 0;
}
diff --git a/subsurfacestartup.c b/subsurfacestartup.c
index 6d3714b91..b16c1fb9c 100644
--- a/subsurfacestartup.c
+++ b/subsurfacestartup.c
@@ -94,7 +94,8 @@ static void print_help()
printf("\n --help|-h This help text");
printf("\n --import logfile ... Logs before this option is treated as base, everything after is imported");
printf("\n --verbose|-v Verbose debug (repeat to increase verbosity)");
- printf("\n --version Prints current version\n\n");
+ printf("\n --version Prints current version");
+ printf("\n --win32console Create a dedicated console if needed (Windows only). Add option before everything else\n\n");
}
void parse_argument(const char *arg)
@@ -130,6 +131,8 @@ void parse_argument(const char *arg)
print_version();
exit(0);
}
+ if (strcmp(arg, "--win32console") == 0)
+ return;
/* fallthrough */
case 'p':
/* ignore process serial number argument when run as native macosx app */
diff --git a/windows.c b/windows.c
index c76a73048..99720cf9d 100644
--- a/windows.c
+++ b/windows.c
@@ -2,6 +2,7 @@
/* implements Windows specific functions */
#include "dive.h"
#include "display.h"
+#define _WIN32_WINNT 0x500
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
@@ -199,3 +200,79 @@ int subsurface_zip_close(struct zip *zip)
{
return zip_close(zip);
}
+
+/* win32 console */
+static struct {
+ bool allocated;
+ UINT cp;
+ FILE *out, *err;
+} console_desc;
+
+void subsurface_console_init(bool dedicated)
+{
+ /* if this is a console app already, do nothing */
+#ifndef WIN32_CONSOLE_APP
+ /* just in case of multiple calls */
+ memset((void *)&console_desc, 0, sizeof(console_desc));
+ /* the AttachConsole(..) call can be used to determine if the parent process
+ * is a terminal. if it succeeds, there is no need for a dedicated console
+ * window and we don't need to call the AllocConsole() function. on the other
+ * hand if the user has set the 'dedicated' flag to 'true' and if AttachConsole()
+ * has failed, we create a dedicated console window.
+ */
+ console_desc.allocated = AttachConsole(ATTACH_PARENT_PROCESS);
+ if (console_desc.allocated)
+ dedicated = false;
+ if (!console_desc.allocated && dedicated)
+ console_desc.allocated = AllocConsole();
+ if (!console_desc.allocated)
+ return;
+
+ console_desc.cp = GetConsoleCP();
+ SetConsoleOutputCP(CP_UTF8); /* make the ouput utf8 */
+
+ /* set some console modes; we don't need to reset these back.
+ * ENABLE_EXTENDED_FLAGS = 0x0080, ENABLE_QUICK_EDIT_MODE = 0x0040 */
+ HANDLE h_in = GetStdHandle(STD_INPUT_HANDLE);
+ if (h_in) {
+ SetConsoleMode(h_in, 0x0080 | 0x0040);
+ CloseHandle(h_in);
+ }
+
+ /* dedicated only; disable the 'x' button as it will close the main process as well */
+ HWND h_cw = GetConsoleWindow();
+ if (h_cw && dedicated) {
+ SetWindowTextA(h_cw, "Subsurface Console");
+ HMENU h_menu = GetSystemMenu(h_cw, 0);
+ if (h_menu) {
+ EnableMenuItem(h_menu, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED);
+ DrawMenuBar(h_cw);
+ }
+ SetConsoleCtrlHandler(NULL, TRUE); /* disable the CTRL handler */
+ }
+
+ /* redirect; on win32, CON is a reserved pipe target, like NUL */
+ console_desc.out = freopen("CON", "w", stdout);
+ console_desc.err = freopen("CON", "w", stderr);
+ if (!dedicated)
+ puts(""); /* add an empty line */
+#endif
+}
+
+void subsurface_console_exit(void)
+{
+#ifndef WIN32_CONSOLE_APP
+ if (!console_desc.allocated)
+ return;
+
+ /* close handles */
+ if (console_desc.out)
+ fclose(console_desc.out);
+ if (console_desc.err)
+ fclose(console_desc.err);
+
+ /* reset code page and free */
+ SetConsoleOutputCP(console_desc.cp);
+ FreeConsole();
+#endif
+}