log/windows: Integrate implementation of --wconsole

This makes it so we no longer try to steal the console back to a log
file when using --wconsole with the new redirection code. Now the
--wconsole switch triggers a special mode of the log file manager that
uses a native console instead of log files.

As a necessary bonus to appease compilers, the GUI2 version info dialog
now uses the correct log file path when not started with the --wconsole
switch. Yay!
This commit is contained in:
Ignacio R. Morelle 2015-11-23 01:59:36 -03:00
parent bc9fb0c111
commit 53ed94da25
9 changed files with 97 additions and 147 deletions

View file

@ -251,8 +251,6 @@
<Unit filename="../../src/desktop/open.hpp" />
<Unit filename="../../src/desktop/version.cpp" />
<Unit filename="../../src/desktop/version.hpp" />
<Unit filename="../../src/desktop/windows_console.cpp" />
<Unit filename="../../src/desktop/windows_console.hpp" />
<Unit filename="../../src/desktop/windows_tray_notification.cpp" />
<Unit filename="../../src/desktop/windows_tray_notification.hpp" />
<Unit filename="../../src/dialogs.cpp" />

View file

@ -1148,7 +1148,6 @@ set(libwesnoth-game_STAT_SRC
if(WIN32)
set(libwesnoth-game_STAT_SRC
${libwesnoth-game_STAT_SRC}
desktop/windows_console.cpp
desktop/windows_tray_notification.cpp
)
endif(WIN32)

View file

@ -635,7 +635,6 @@ wesnoth_sources = Split("""
if env["PLATFORM"] == "win32":
wesnoth_sources.append("desktop/windows_tray_notification.cpp")
wesnoth_sources.append("desktop/windows_console.cpp")
if env["PLATFORM"] == 'darwin':
wesnoth_sources.append("desktop/apple_notification.mm")

View file

@ -1,101 +0,0 @@
/*
Copyright (C) 2014 - 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "desktop/windows_console.hpp"
#include "log.hpp"
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501 // XP and later
#include <windows.h>
#include <cstdio>
#include <boost/scoped_ptr.hpp>
static lg::log_domain log_desktop("desktop");
#define ERR_DU LOG_STREAM(err, log_desktop)
#define LOG_DU LOG_STREAM(info, log_desktop)
namespace {
class win32_console_manager
{
public:
win32_console_manager()
{
#if 0
// Because this runs before cmdline processing, enable this block for
// debugging purposes if necessary.
lg::set_log_domain_severity("desktop", lg::debug);
#endif
if(AttachConsole(ATTACH_PARENT_PROCESS)) {
LOG_DU << "win32_console: attached to parent process console\n";
} else if(AllocConsole()) {
LOG_DU << "win32_console: attached to own console\n";
} else {
ERR_DU << "win32_console: failed to attach or allocate console!";
return;
}
LOG_DU << "win32_console: stdin to console\n";
freopen("CONIN$", "rb", stdin);
LOG_DU << "win32_console: stdout to console\n";
std::cout.flush();
freopen("CONOUT$", "wb", stdout);
LOG_DU << "win32_console: stderr to console\n";
std::cerr.flush();
freopen("CONOUT$", "wb", stderr);
LOG_DU << "win32_console: init complete\n";
}
~win32_console_manager()
{
FreeConsole();
LOG_DU << "win32_console: uninit complete\n";
}
};
boost::scoped_ptr<win32_console_manager> conman;
} // end anonymous namespace
namespace desktop {
void enable_win32_console()
{
if(!conman) {
conman.reset(new win32_console_manager());
} else {
ERR_DU << "win32_console: Console already enabled!\n";
}
}
void disable_win32_console()
{
conman.reset(NULL);
}
bool is_win32_console_enabled()
{
return conman != NULL;
}
} // end namespace desktop

View file

@ -1,29 +0,0 @@
/*
Copyright (C) 2014 - 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef DESKTOP_WIN32_CONSOLE_HPP_INCLUDED
#define DESKTOP_WIN32_CONSOLE_HPP_INCLUDED
namespace desktop {
void enable_win32_console();
void disable_win32_console();
bool is_win32_console_enabled();
}
#endif // DESKTOP_WIN32_CONSOLE_HPP_INCLUDED

View file

@ -20,9 +20,6 @@
#include "desktop/clipboard.hpp"
#include "desktop/open.hpp"
#include "desktop/version.hpp"
#ifdef _WIN32
#include "desktop/windows_console.hpp"
#endif
#include "filesystem.hpp"
#include "formula_string_utils.hpp"
#include "game_config.hpp"
@ -41,6 +38,9 @@
#include "gui/widgets/stacked_widget.hpp"
#include "gui/widgets/text.hpp"
#include "gui/widgets/window.hpp"
#ifdef _WIN32
#include "log_windows.hpp"
#endif
#include "serialization/string_utils.hpp"
#include "gettext.hpp"
@ -93,7 +93,7 @@ tgame_version::tgame_version()
, browse_wid_stem_("browse_")
, path_map_()
#ifdef _WIN32
, log_path_(game_config::wesnoth_program_dir + "\\stderr.txt")
, log_path_(lg::log_file_path())
#endif
, deps_()
, opts_(game_config::optional_features_table())
@ -199,7 +199,7 @@ void tgame_version::pre_show(CVideo& /*video*/, twindow& window)
boost::bind(&tgame_version::browse_directory_callback,
this,
log_path_));
stderr_button.set_active(!desktop::is_win32_console_enabled());
stderr_button.set_active(!log_path_.empty());
#endif
//

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Copyright (C) 2014 - 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
@ -207,7 +207,7 @@ void log_init_panic(const libc_error& e,
class log_file_manager : private boost::noncopyable
{
public:
log_file_manager();
log_file_manager(bool native_console = false);
~log_file_manager();
/**
@ -228,9 +228,23 @@ public:
*/
void move_log_file(const std::string& log_dir);
/**
* Switches to using a native console instead of log file redirection.
*
* This is an irreversible operation right now. This might change later if
* someone deems it useful.
*/
void enable_native_console_output();
/**
* Returns whether we are using a native console instead of a log file.
*/
bool console_enabled() const;
private:
std::string fn_;
std::string cur_path_;
bool use_wincon_;
enum STREAM_ID {
STREAM_STDOUT = 1,
@ -266,12 +280,18 @@ private:
bool truncate);
};
log_file_manager::log_file_manager()
log_file_manager::log_file_manager(bool native_console)
: fn_(unique_log_filename())
, cur_path_()
, use_wincon_()
{
DBG_LS << "Early init message\n";
if(native_console) {
enable_native_console_output();
return;
}
//
// We use the Windows temp dir on startup,
//
@ -359,6 +379,44 @@ void log_file_manager::do_redirect_single_stream(const std::string& file_path,
DBG_LS << stream << ' ' << cur_path_ << " -> " << file_path << " [side B]\n";
}
bool log_file_manager::console_enabled() const
{
return use_wincon_;
}
void log_file_manager::enable_native_console_output()
{
if(AttachConsole(ATTACH_PARENT_PROCESS)) {
LOG_LS << "Attached parent process console.\n";
} else if(AllocConsole()) {
LOG_LS << "Allocated own console.\n";
} else {
ERR_LS << "Console attachment or allocation failed!\n";
return;
}
DBG_LS << "stderr to console\n";
fflush(stderr);
std::cerr.flush();
freopen("CONOUT$", "wb", stderr);
DBG_LS << "stdout to console\n";
fflush(stdout);
std::cout.flush();
freopen("CONOUT$", "wb", stdout);
DBG_LS << "stdin from console\n";
freopen("CONIN$", "rb", stdin);
// At this point the log file has been closed and it's no longer our
// responsibility to clean up anything; Windows will figure out what to do
// when the time comes for the process to exit.
cur_path_.clear();
use_wincon_ = true;
LOG_LS << "Console streams handover complete!\n";
}
boost::scoped_ptr<log_file_manager> lfm;
} // end anonymous namespace
@ -381,11 +439,26 @@ void early_log_file_setup()
lfm.reset(new log_file_manager());
}
void enable_native_console_output()
{
if(lfm) {
lfm->enable_native_console_output();
return;
}
lfm.reset(new log_file_manager(true));
}
void finish_log_file_setup()
{
// Make sure the LFM is actually set up just in case.
early_log_file_setup();
if(lfm->console_enabled()) {
// Nothing to do if running in console mode.
return;
}
static bool setup_complete = false;
if(setup_complete) {

View file

@ -1,5 +1,5 @@
/*
Copyright (C) 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Copyright (C) 2014 - 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
@ -68,6 +68,18 @@ void early_log_file_setup();
*/
void finish_log_file_setup();
/**
* Switches to using a native console instead of log file redirection.
*
* In this mode, the log file is closed (if it was created in the first place)
* and output is sent directly to an attached or allocated console instead.
* This is used to implement the --wconsole command line option.
*
* Using a native console instead of a file has the benefit of allowing to see
* output in real time or redirecting it to a user-specified file.
*/
void enable_native_console_output();
}
#endif

View file

@ -62,7 +62,6 @@
#include "wml_exception.hpp" // for twml_exception
#ifdef _WIN32
#include "desktop/windows_console.hpp"
#include "log_windows.hpp"
#endif // _WIN32
@ -910,8 +909,6 @@ int main(int argc, char** argv)
#endif
#endif //_OPENMP
#ifdef _WIN32
lg::early_log_file_setup();
(void)argc;
(void)argv;
@ -924,10 +921,12 @@ int main(int argc, char** argv)
// here and let program_options ignore the switch later.
for(size_t k = 0; k < args.size(); ++k) {
if(args[k] == "--wconsole") {
desktop::enable_win32_console();
lg::enable_native_console_output();
break;
}
}
lg::early_log_file_setup();
#else
std::vector<std::string> args;
for(int i = 0; i < argc; ++i)