diff --git a/configure.ac b/configure.ac index 360a9632..7f0e4454 100644 --- a/configure.ac +++ b/configure.ac @@ -63,7 +63,7 @@ AC_FUNC_SELECT_ARGTYPES AC_FUNC_STAT AC_CHECK_FUNCS(basename, , AC_CHECK_LIB(gen, basename, LIBS="-lgen $LIBS")) -AC_CHECK_FUNCS(catclose catgets catopen getpid memset mkdir \ +AC_CHECK_FUNCS(alarm catclose catgets catopen getpid memset mkdir \ nl_langinfo putenv regcomp select setenv setlocale sigaction snprintf \ sqrt strcasecmp strcasestr strchr strstr strtol strtoul sync vsnprintf) diff --git a/doc/asciidoc/fluxbox.txt b/doc/asciidoc/fluxbox.txt index 7848f03f..c2e48158 100644 --- a/doc/asciidoc/fluxbox.txt +++ b/doc/asciidoc/fluxbox.txt @@ -1256,9 +1256,8 @@ SIGNALS ------- fluxbox responds to the following signals: -- SIGHUP fluxbox loads the configuration. -- SIGUSR1 Forces reloading of configuration. -- SIGUSR2 Forces reloading of menu file. +- SIGUSR1 restarts fluxbox. +- SIGUSR2 Forces reloading of configuration. AUTHORS ------- diff --git a/src/Debug.hh b/src/Debug.hh index 3688b521..556186f5 100644 --- a/src/Debug.hh +++ b/src/Debug.hh @@ -1,10 +1,12 @@ #ifndef DEBUG_HH #define DEBUG_HH +#ifdef HAVE_CONFIG_H #include "config.h" -#include +#endif // HAVE_CONFIG_H #ifdef DEBUG +#include #define fbdbg std::cerr<<__FILE__<<"("<<__LINE__<< "): " #else #define fbdbg if (false) std::cerr diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am index d54eaaed..610859cc 100644 --- a/src/FbTk/Makefile.am +++ b/src/FbTk/Makefile.am @@ -33,7 +33,7 @@ libFbTk_a_SOURCES = App.hh App.cc \ MultiButtonMenuItem.hh MultiButtonMenuItem.cc \ MenuTheme.hh MenuTheme.cc NotCopyable.hh \ BorderTheme.hh BorderTheme.cc TextTheme.hh TextTheme.cc \ - RefCount.hh SimpleCommand.hh SignalHandler.cc SignalHandler.hh \ + RefCount.hh SimpleCommand.hh \ TextUtils.hh TextUtils.cc Orientation.hh \ Texture.cc Texture.hh TextureRender.hh TextureRender.cc \ Shape.hh Shape.cc \ diff --git a/src/FbTk/SignalHandler.cc b/src/FbTk/SignalHandler.cc deleted file mode 100644 index 5f06210f..00000000 --- a/src/FbTk/SignalHandler.cc +++ /dev/null @@ -1,79 +0,0 @@ -// SignalHandler.cc for FbTk - Fluxbox ToolKit -// Copyright (c) 2002 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#include "SignalHandler.hh" - -namespace FbTk { - -SignalEventHandler *SignalHandler::s_signal_handler[NSIG]; - -SignalHandler::SignalHandler() { - // clear signal list - for (int i=0; i < NSIG; ++i) - s_signal_handler[i] = 0; -} - -SignalHandler &SignalHandler::instance() { - static SignalHandler singleton; - return singleton; -} - -bool SignalHandler::registerHandler(int signum, SignalEventHandler *eh, - SignalEventHandler **oldhandler_ret) { - // must be less than NSIG - if (signum >= NSIG) - return false; - - // get old signal handler for this signum - if (oldhandler_ret != 0) - *oldhandler_ret = s_signal_handler[signum]; - -#ifdef HAVE_SIGACTION - struct sigaction sa; - // set callback - sa.sa_handler = SignalHandler::handleSignal; - sigemptyset (&sa.sa_mask); - sa.sa_flags = 0; - - if (sigaction(signum, &sa, 0) == -1) - return false; -#else - // Fallback code for Windows and other platforms lacking sigaction. - if (signal(signum, &SignalHandler::handleSignal) == SIG_ERR) { - return false; - } -#endif - s_signal_handler[signum] = eh; - - return true; -} - -void SignalHandler::handleSignal(int signum) { - if (signum >= NSIG) - return; - // make sure we got a handler for this signal - if (s_signal_handler[signum] != 0) { - s_signal_handler[signum]->handleSignal(signum); - } -} - -} - diff --git a/src/FbTk/SignalHandler.hh b/src/FbTk/SignalHandler.hh deleted file mode 100644 index 774f4b15..00000000 --- a/src/FbTk/SignalHandler.hh +++ /dev/null @@ -1,66 +0,0 @@ -// SignalHandler.hh for FbTk -// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at fluxbox dot org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#ifndef FBTK_SIGNALHANDLER_HH -#define FBTK_SIGNALHANDLER_HH - -#include - -namespace FbTk { - -/// Base class that SignalHandler calls when it gets a signal -/// Use this to catch system signals -class SignalEventHandler { -public: - virtual void handleSignal(int signum) = 0; - virtual ~SignalEventHandler() { } -}; - -/// Handles system signals, singleton. -/** - Usage: inherit the class SignalEventHandler and then register - it to SignalHandler by calling registerHandler with - a signal number -*/ -class SignalHandler { -public: - /// get singleton object - static SignalHandler &instance(); - /** - Register an event handler - @return true on success else false - @param signum signal number - @param eh event handler - @param oldhandler_ret return handler to old sighandler - */ - bool registerHandler(int signum, SignalEventHandler *eh, SignalEventHandler **oldhandler_ret = 0); - -private: - SignalHandler(); - - static void handleSignal(int signum); - - static SignalEventHandler *s_signal_handler[NSIG]; ///< NSIG defined in signal.h -}; - -} // end namespace FbTk - -#endif // FBTK_SIGNALHANDLER_HH diff --git a/src/Makefile.am b/src/Makefile.am index 257bdbbb..eb5ab049 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,6 +54,7 @@ defaults.hh: Makefile echo '#else'; \ echo '#define PATHPREFIX'; \ echo '#endif'; \ + echo '#define CONFIG_VERSION 13'; \ echo '#define DEFAULTMENU PATHPREFIX "$(DEFAULT_MENU)"'; \ echo '#define DEFAULTSTYLE PATHPREFIX "$(DEFAULT_STYLE)"'; \ echo '#define DEFAULTKEYSFILE PATHPREFIX "$(DEFAULT_KEYSFILE)"'; \ @@ -123,7 +124,9 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \ FbAtoms.hh FbAtoms.cc FbWinFrame.hh FbWinFrame.cc \ FbWinFrameTheme.hh FbWinFrameTheme.cc \ fluxbox.cc fluxbox.hh \ - Keys.cc Keys.hh main.cc \ + Keys.cc Keys.hh \ + main.cc \ + cli.hh cli_cfiles.cc cli_options.cc cli_info.cc \ RootTheme.hh RootTheme.cc \ FbRootWindow.hh FbRootWindow.cc \ OSDWindow.hh OSDWindow.cc \ diff --git a/src/cli.hh b/src/cli.hh new file mode 100644 index 00000000..ac1e655c --- /dev/null +++ b/src/cli.hh @@ -0,0 +1,50 @@ +#ifndef CLI_HH +#define CLI_HH + +// cli.hh for Fluxbox Window Manager +// Copyright (c) 2014 - Mathias Gumz +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#include +#include + +namespace FluxboxCli { + +struct Options { + Options(); + int parse(int argc, char** argv); + + std::string session_display; + std::string rc_path; + std::string rc_file; + std::string log_filename; + bool xsync; +}; + + +void showInfo(std::ostream&); + +void setupConfigFiles(const std::string& dirname, const std::string& rc); +void updateConfigFilesIfNeeded(const std::string& rc_file); + +} + +#endif /* end of include guard: CLI_HH */ + diff --git a/src/cli_cfiles.cc b/src/cli_cfiles.cc new file mode 100644 index 00000000..b32083ce --- /dev/null +++ b/src/cli_cfiles.cc @@ -0,0 +1,170 @@ +// cli_cfiles.cc for Fluxbox Window Manager +// Copyright (c) 2014 - Mathias Gumz +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#include "cli.hh" +#include "defaults.hh" + +#include "Debug.hh" +#include "FbTk/FileUtil.hh" +#include "FbTk/I18n.hh" +#include "FbTk/Resource.hh" +#include "FbTk/StringUtil.hh" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#ifdef HAVE_CSTRING + #include +#else + #include +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#include +#endif // HAVE_SYS_STAT_H + +#ifdef HAVE_UNISTD_H + #include +#endif + +#ifdef HAVE_CSTDLIB + #include +#else + #include +#endif + + +using std::string; +using std::endl; +using std::cerr; + + +#ifdef _WIN32 +/** + Wrapper function for Windows builds - mkdir takes only one param. +*/ +static int mkdir(const char *dirname, int /*permissions*/) { + return mkdir(dirname); +} +#endif + + +/** + setup the configutation files in + home directory +*/ +void FluxboxCli::setupConfigFiles(const std::string& dirname, const std::string& rc) { + + _FB_USES_NLS; + + const bool has_dir = FbTk::FileUtil::isDirectory(dirname.c_str()); + + + struct CFInfo { + bool create_file; + const char* default_name; + const std::string filename; + } cfiles[] = { + { !has_dir, DEFAULT_INITFILE, rc }, + { !has_dir, DEFAULTKEYSFILE, dirname + "/keys" }, + { !has_dir, DEFAULTMENU, dirname + "/menu" }, + { !has_dir, DEFAULT_APPSFILE, dirname + "/apps" }, + { !has_dir, DEFAULT_OVERLAY, dirname + "/overlay" }, + { !has_dir, DEFAULT_WINDOWMENU, dirname + "/windowmenu" } + }; + const size_t nr_of_cfiles = sizeof(cfiles)/sizeof(CFInfo); + + + if (has_dir) { // check if anything with these names exists, if not create new + for (size_t i = 0; i < nr_of_cfiles; ++i) { + cfiles[i].create_file = access(cfiles[i].filename.c_str(), F_OK); + } + } else { + + fbdbg << "Creating dir: " << dirname << endl; + if (mkdir(dirname.c_str(), 0700)) { + fprintf(stderr, _FB_CONSOLETEXT(Fluxbox, ErrorCreatingDirectory, + "Can't create %s directory", + "Can't create a directory, one %s for directory name").c_str(), + dirname.c_str()); + cerr << endl; + return; + } + } + + bool sync_fs = false; + + // copy default files if needed + for (size_t i = 0; i < nr_of_cfiles; ++i) { + if (cfiles[i].create_file) { + FbTk::FileUtil::copyFile(FbTk::StringUtil::expandFilename(cfiles[i].default_name).c_str(), cfiles[i].filename.c_str()); + sync_fs = true; + } + } +#ifdef HAVE_SYNC + if (sync_fs) { + sync(); + } +#endif +} + + + +// configs might be out of date, so run fluxbox-update_configs +// if necassary. +void FluxboxCli::updateConfigFilesIfNeeded(const std::string& rc_file) { + + FbTk::ResourceManager r_mgr(rc_file.c_str(), false); + FbTk::Resource c_version(r_mgr, 0, "session.configVersion", "Session.ConfigVersion"); + + if (!r_mgr.load(rc_file.c_str())) { + _FB_USES_NLS; + cerr << _FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "") + << ": " + << rc_file << endl; + return; + } + + if (*c_version < CONFIG_VERSION) { + + fbdbg << "updating config files from version " + << *c_version + << " to " + << CONFIG_VERSION + << endl; + + string commandargs = realProgramName("fluxbox-update_configs"); + commandargs += " -rc " + rc_file; + + if (system(commandargs.c_str())) { + fbdbg << "running '" + << commandargs + << "' failed." << endl; + } +#ifdef HAVE_SYNC + sync(); +#endif // HAVE_SYNC + } +} + + diff --git a/src/cli_info.cc b/src/cli_info.cc new file mode 100644 index 00000000..6156d565 --- /dev/null +++ b/src/cli_info.cc @@ -0,0 +1,191 @@ +// cli_info.cc for Fluxbox Window Manager +// Copyright (c) 2014 - Mathias Gumz +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#include "cli.hh" +#include "defaults.hh" +#include "version.h" + +#include "FbTk/I18n.hh" +#include "FbTk/StringUtil.hh" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#ifdef HAVE_CSTRING + #include +#else + #include +#endif + +using std::endl; +using std::ostream; + +void FluxboxCli::showInfo(ostream &ostr) { + _FB_USES_NLS; + ostr << + _FB_CONSOLETEXT(Common, FluxboxVersion, "Fluxbox version", "Fluxbox version heading") + << ": " + << __fluxbox_version < 0) + ostr << _FB_CONSOLETEXT(Common, SvnRevision, "GIT Revision", "Revision number in GIT repositary") + << ": " + << gitrevision() << endl; +#if defined(__DATE__) && defined(__TIME__) + ostr << _FB_CONSOLETEXT(Common, Compiled, "Compiled", "Time fluxbox was compiled") + << ": " + << __DATE__ + << " " + << __TIME__ << endl; +#endif +#ifdef __fluxbox_compiler + ostr << _FB_CONSOLETEXT(Common, Compiler, "Compiler", "Compiler used to build fluxbox") + << ": " + << __fluxbox_compiler << endl; +#endif // __fluxbox_compiler +#ifdef __fluxbox_compiler_version + ostr << _FB_CONSOLETEXT(Common, CompilerVersion, "Compiler version", "Compiler version used to build fluxbox") + << ": " + << __fluxbox_compiler_version << endl; +#endif // __fluxbox_compiler_version + + ostr << endl + <<_FB_CONSOLETEXT(Common, Defaults, "Defaults", "Default values compiled in") + << ": " << endl; + + ostr <<_FB_CONSOLETEXT(Common, DefaultMenuFile, " menu", "default menu file (right aligned - make sure same width as other default values)") + << ": " + << FbTk::StringUtil::expandFilename(DEFAULTMENU) << endl; + ostr << _FB_CONSOLETEXT(Common, DefaultStyle, " style", "default style (right aligned - make sure same width as other default values)") + << ": " + << FbTk::StringUtil::expandFilename(DEFAULTSTYLE) << endl; + + ostr << _FB_CONSOLETEXT(Common, DefaultKeyFile, " keys", "default key file (right aligned - make sure same width as other default values)") + << ": " + << FbTk::StringUtil::expandFilename(DEFAULTKEYSFILE) << endl; + ostr << _FB_CONSOLETEXT(Common, DefaultInitFile, " init", "default init file (right aligned - make sure same width as other default values)") + << ": " + << FbTk::StringUtil::expandFilename(DEFAULT_INITFILE) << endl; + +#ifdef NLS + ostr << _FB_CONSOLETEXT(Common, DefaultLocalePath, " nls", "location for localization files (right aligned - make sure same width as other default values)") + << ": " + << FbTk::StringUtil::expandFilename(LOCALEPATH) << endl; +#endif + + const char NOT[] = "-"; + ostr << endl + << _FB_CONSOLETEXT(Common, CompiledOptions, "Compiled options", "Options used when compiled") + << " (" << NOT << " => " + << _FB_CONSOLETEXT(Common, Disabled, "disabled", "option is turned off") << "): " << endl + << + +/**** NOTE: This list is in alphabetical order! ****/ + +#ifndef HAVE_FRIBIDI + NOT << +#endif + "BIDI" << endl << + +#ifndef DEBUG + NOT << +#endif // DEBUG + "DEBUG" << endl << + +#ifndef USE_EWMH + NOT << +#endif // USE_EWMH + "EWMH" << endl << + +#ifndef HAVE_IMLIB2 + NOT<< +#endif // HAVE_IMLIB2 + "IMLIB2" << endl << + +#ifndef NLS + NOT<< +#endif // NLS + "NLS" << endl << + +#ifndef REMEMBER + NOT << +#endif // REMEMBER + "REMEMBER" << endl << + +#ifndef HAVE_XRENDER + NOT << +#endif // HAVE_XRENDER + "RENDER" << endl << + +#ifndef SHAPE + NOT << +#endif // SHAPE + "SHAPE" << endl << + +#ifndef USE_SLIT + NOT << +#endif // SLIT + "SLIT" << endl << + +#ifndef USE_SYSTRAY + NOT << +#endif + "SYSTEMTRAY" << endl << + + +#ifndef USE_TOOLBAR + NOT << +#endif // USE_TOOLBAR + "TOOLBAR" << endl << + +#ifndef HAVE_RANDR + NOT << +#endif + "RANDR" << +#ifdef HAVE_RANDR1_2 + "1.2" << +#endif + endl << + +#ifndef USE_XFT + NOT << +#endif // USE_XFT + "XFT" << endl << + +#ifndef XINERAMA + NOT << +#endif // XINERAMA + "XINERAMA" << endl << + +#ifndef USE_XMB + NOT << +#endif // USE_XMB + "XMB" << endl << + +#ifndef HAVE_XPM + NOT << +#endif // HAVE_XPM + "XPM" << endl + + << endl; +} + diff --git a/src/cli_options.cc b/src/cli_options.cc new file mode 100644 index 00000000..1455ea1e --- /dev/null +++ b/src/cli_options.cc @@ -0,0 +1,158 @@ +// cli_options.cc for Fluxbox Window Manager +// Copyright (c) 2014 - Mathias Gumz +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +#include "cli.hh" +#include "version.h" +#include "defaults.hh" +#include "Debug.hh" + +#include "FbTk/App.hh" +#include "FbTk/FileUtil.hh" +#include "FbTk/StringUtil.hh" +#include "FbTk/Theme.hh" +#include "FbTk/I18n.hh" +#include "FbTk/Command.hh" +#include "FbTk/CommandParser.hh" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#ifdef HAVE_CSTDLIB + #include +#else + #include +#endif + +#ifdef HAVE_CSTRING + #include +#else + #include +#endif + +#include + +using std::cerr; +using std::cout; +using std::endl; +using std::string; + +FluxboxCli::Options::Options() : xsync(false) { + + const char* env = getenv("DISPLAY"); + if (env && strlen(env) > 0) { + session_display.assign(env); + } + + string fname = std::string("~/.") + realProgramName("fluxbox"); + rc_path = FbTk::StringUtil::expandFilename(fname); + + if (!rc_path.empty()) { + rc_file = rc_path + "/init"; + } +} + +int FluxboxCli::Options::parse(int argc, char** argv) { + + _FB_USES_NLS; + + int i; + for (i = 1; i < argc; ++i) { + string arg(argv[i]); + if (arg == "-rc" || arg == "--rc") { + // look for alternative rc file to use + + if ((++i) >= argc) { + cerr<<_FB_CONSOLETEXT(main, RCRequiresArg, + "error: '-rc' requires an argument", + "the -rc option requires a file argument")<rc_file = argv[i]; + + } else if (arg == "-display" || arg == "--display") { + // check for -display option... to run on a display other than the one + // set by the environment variable DISPLAY + + if ((++i) >= argc) { + cerr<<_FB_CONSOLETEXT(main, DISPLAYRequiresArg, + "error: '-display' requires an argument", + "")<session_display = argv[i]; + if (!FbTk::App::setenv("DISPLAY", argv[i])) { + cerr<<_FB_CONSOLETEXT(main, WarnDisplayEnv, + "warning: couldn't set environment variable 'DISPLAY'", + "")<= argc) { + cerr<<_FB_CONSOLETEXT(main, LOGRequiresArg, + "error: '-log' needs an argument", "")<log_filename = argv[i]; + } else if (arg == "-sync" || arg == "--sync") { + this->xsync = true; + } else if (arg == "-help" || arg == "-h" || arg == "--help") { + // print program usage and command line options + printf(_FB_CONSOLETEXT(main, Usage, + "Fluxbox %s : (c) %s Fluxbox Team\n" + "Website: http://www.fluxbox.org/\n\n" + "-display \t\tuse display connection.\n" + "-screen \trun on specified screens only.\n" + "-rc \t\t\tuse alternate resource file.\n" + "-version\t\t\tdisplay version and exit.\n" + "-info\t\t\t\tdisplay some useful information.\n" + "-list-commands\t\t\tlist all valid key commands.\n" + "-sync\t\t\t\tsynchronize with X server for debugging.\n" + "-log \t\t\tlog output to file.\n" + "-help\t\t\t\tdisplay this help text and exit.\n\n", + + "Main usage string. Please lay it out nicely. There is one %s that is given the version").c_str(), + __fluxbox_version, "2001-2014"); + return EXIT_SUCCESS; + } else if (arg == "-info" || arg == "-i" || arg == "--info") { + FluxboxCli::showInfo(cout); + return EXIT_SUCCESS; + } else if (arg == "-list-commands" || arg == "--list-commands") { + FbTk::CommandParser::CreatorMap cmap = FbTk::CommandParser::instance().creatorMap(); + FbTk::CommandParser::CreatorMap::const_iterator it = cmap.begin(); + const FbTk::CommandParser::CreatorMap::const_iterator it_end = cmap.end(); + for (; it != it_end; ++it) + cout << it->first << endl; + return EXIT_SUCCESS; + } else if (arg == "-verbose" || arg == "--verbose") { + FbTk::ThemeManager::instance().setVerbose(true); + } + } + return -1; +} + diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 8305b8ad..07419ba8 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -177,11 +177,15 @@ int handleXErrors(Display *d, XErrorEvent *e) { // kill(0, 2); } #endif // !DEBUG - return False; } +int handleXIOErrors(Display* d) { + cerr << "Fluxbox: XIOError: lost connection to display.\n"; + exit(1); +} + /* functor to call a memberfunction with by a reference argument other places needs this helper as well it should be moved @@ -290,21 +294,8 @@ Fluxbox::Fluxbox(int argc, char **argv, s_kwm2_dockwindow = XInternAtom(disp, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); // setup X error handler - XSetErrorHandler((XErrorHandler) handleXErrors); - - //catch system signals - SignalHandler &sigh = SignalHandler::instance(); - sigh.registerHandler(SIGSEGV, this); - sigh.registerHandler(SIGFPE, this); - sigh.registerHandler(SIGTERM, this); - sigh.registerHandler(SIGINT, this); -#ifndef _WIN32 - sigh.registerHandler(SIGPIPE, this); // e.g. output sent to grep - sigh.registerHandler(SIGCHLD, this); - sigh.registerHandler(SIGHUP, this); - sigh.registerHandler(SIGUSR1, this); - sigh.registerHandler(SIGUSR2, this); -#endif + XSetErrorHandler(handleXErrors); + XSetIOErrorHandler(handleXIOErrors); // // setup timer @@ -896,58 +887,6 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { } } -/// handle system signals -void Fluxbox::handleSignal(int signum) { - _FB_USES_NLS; - - static int re_enter = 0; - - switch (signum) { -#ifndef _WIN32 - case SIGCHLD: // we don't want the child process to kill us - // more than one process may have terminated - while (waitpid(-1, 0, WNOHANG | WUNTRACED) > 0); - break; - case SIGHUP: - restart(); - break; - case SIGUSR1: - load_rc(); - break; - case SIGUSR2: - reconfigure(); - break; -#endif - case SIGSEGV: - abort(); - break; - case SIGFPE: - case SIGINT: -#ifndef _WIN32 - case SIGPIPE: -#endif - case SIGTERM: - shutdown(); - break; - default: - fprintf(stderr, - _FB_CONSOLETEXT(BaseDisplay, SignalCaught, "%s: signal %d caught\n", "signal catch debug message. Include %s for Command and %d for signal number").c_str(), - m_argv[0], signum); - - if (! m_starting && ! re_enter) { - re_enter = 1; - cerr<<_FB_CONSOLETEXT(BaseDisplay, ShuttingDown, "Shutting Down\n", "Quitting because of signal, end with newline"); - shutdown(); - } - - - cerr<<_FB_CONSOLETEXT(BaseDisplay, Aborting, "Aborting... dumping core\n", "Aboring and dumping core, end with newline"); - abort(); - break; - } -} - - void Fluxbox::windowDied(Focusable &focusable) { FluxboxWindow *fbwin = focusable.fbwindow(); @@ -1122,18 +1061,30 @@ void Fluxbox::restart(const char *prog) { } } -/// prepares fluxbox for a shutdown -void Fluxbox::shutdown() { +// prepares fluxbox for a shutdown. when x_wants_down is != 0 we assume that +// the xserver is about to shutdown or is in the midst of shutting down +// already. trying to cleanup over a shaky xserver connection is pointless and +// might lead to hangups. +void Fluxbox::shutdown(int x_wants_down) { if (m_shutdown) return; + Display *dpy = FbTk::App::instance()->display(); m_shutdown = true; - XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime); +#ifdef HAVE_ALARM + // give ourself 2 seconds (randomly picked randon number) to shutdown + // and then try to reenter signal handling. a bad race condition might + // lead to an inifite loop and this is some kind of last resort + alarm(2); +#endif - STLUtil::forAll(m_screen_list, mem_fun(&BScreen::shutdown)); + XSetInputFocus(dpy, PointerRoot, None, CurrentTime); - sync(false); + if (x_wants_down == 0) { + STLUtil::forAll(m_screen_list, mem_fun(&BScreen::shutdown)); + sync(false); + } } /// saves resources diff --git a/src/fluxbox.hh b/src/fluxbox.hh index f83934a1..f6a8f26f 100644 --- a/src/fluxbox.hh +++ b/src/fluxbox.hh @@ -28,23 +28,22 @@ #include "FbTk/App.hh" #include "FbTk/Resource.hh" #include "FbTk/Timer.hh" -#include "FbTk/SignalHandler.hh" #include "FbTk/Signal.hh" #include "AttentionNoticeHandler.hh" #include +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + #ifdef HAVE_CSTDIO #include #else #include #endif -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif // HAVE_CONFIG_H - #ifdef TIME_WITH_SYS_TIME #include #include @@ -74,7 +73,6 @@ class FbAtoms; singleton type */ class Fluxbox : public FbTk::App, - public FbTk::SignalEventHandler, private FbTk::SignalTracker { public: Fluxbox(int argc, char **argv, @@ -137,7 +135,7 @@ public: void maskWindowEvents(Window w, FluxboxWindow *bw) { m_masked = w; m_masked_window = bw; } - void shutdown(); + void shutdown(int x_wants_down = 0); void load_rc(BScreen &scr); void saveStyleFilename(const char *val) { m_rc_stylefile = (val == 0 ? "" : val); } void saveWindowSearch(Window win, WinClient *winclient); @@ -152,8 +150,6 @@ public: void restart(const char *command = 0); void reconfigure(); - /// handle any system signal sent to the application - void handleSignal(int signum); /// todo, remove this. just temporary void updateFrameExtents(FluxboxWindow &win); @@ -168,6 +164,7 @@ public: bool isStartup() const { return m_starting; } bool isRestarting() const { return m_restarting; } + bool isShuttingDown() const { return m_shutdown; } const std::string &getRestartArgument() const { return m_restart_argument; } diff --git a/src/main.cc b/src/main.cc index f77e8e5d..ebe77185 100644 --- a/src/main.cc +++ b/src/main.cc @@ -27,13 +27,9 @@ #include "fluxbox.hh" #include "version.h" #include "defaults.hh" +#include "cli.hh" -#include "Debug.hh" - -#include "FbTk/Theme.hh" #include "FbTk/I18n.hh" -#include "FbTk/CommandParser.hh" -#include "FbTk/FileUtil.hh" #include "FbTk/StringUtil.hh" //use GNU extensions @@ -41,28 +37,16 @@ #define _GNU_SOURCE #endif // _GNU_SOURCE -#ifdef HAVE_CSTDLIB - #include -#else - #include -#endif - -#ifdef HAVE_CSTRING - #include -#else - #include -#endif - #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_SYS_STAT_H -#include -#include -#endif // HAVE_SYS_STAT_H +#ifdef HAVE_SYS_WAIT_H +#include +#endif // HAVE_SYS_WAIT_H -#include + +#include #include #include @@ -80,377 +64,107 @@ using std::bad_cast; using std::bad_alloc; using std::exception; -static void showInfo(ostream &ostr) { - _FB_USES_NLS; - ostr << - _FB_CONSOLETEXT(Common, FluxboxVersion, "Fluxbox version", "Fluxbox version heading") - << ": " - << __fluxbox_version < 0) - ostr << _FB_CONSOLETEXT(Common, SvnRevision, "GIT Revision", "Revision number in GIT repositary") - << ": " - << gitrevision() << endl; -#if defined(__DATE__) && defined(__TIME__) - ostr << _FB_CONSOLETEXT(Common, Compiled, "Compiled", "Time fluxbox was compiled") - << ": " - << __DATE__ - << " " - << __TIME__ << endl; -#endif -#ifdef __fluxbox_compiler - ostr << _FB_CONSOLETEXT(Common, Compiler, "Compiler", "Compiler used to build fluxbox") - << ": " - << __fluxbox_compiler << endl; -#endif // __fluxbox_compiler -#ifdef __fluxbox_compiler_version - ostr << _FB_CONSOLETEXT(Common, CompilerVersion, "Compiler version", "Compiler version used to build fluxbox") - << ": " - << __fluxbox_compiler_version << endl; -#endif // __fluxbox_compiler_version +auto_ptr fluxbox; - ostr << endl - <<_FB_CONSOLETEXT(Common, Defaults, "Defaults", "Default values compiled in") - << ": " << endl; - - ostr <<_FB_CONSOLETEXT(Common, DefaultMenuFile, " menu", "default menu file (right aligned - make sure same width as other default values)") - << ": " - << FbTk::StringUtil::expandFilename(DEFAULTMENU) << endl; - ostr << _FB_CONSOLETEXT(Common, DefaultStyle, " style", "default style (right aligned - make sure same width as other default values)") - << ": " - << FbTk::StringUtil::expandFilename(DEFAULTSTYLE) << endl; - - ostr << _FB_CONSOLETEXT(Common, DefaultKeyFile, " keys", "default key file (right aligned - make sure same width as other default values)") - << ": " - << FbTk::StringUtil::expandFilename(DEFAULTKEYSFILE) << endl; - ostr << _FB_CONSOLETEXT(Common, DefaultInitFile, " init", "default init file (right aligned - make sure same width as other default values)") - << ": " - << FbTk::StringUtil::expandFilename(DEFAULT_INITFILE) << endl; - -#ifdef NLS - ostr << _FB_CONSOLETEXT(Common, DefaultLocalePath, " nls", "location for localization files (right aligned - make sure same width as other default values)") - << ": " - << FbTk::StringUtil::expandFilename(LOCALEPATH) << endl; -#endif - - const char NOT[] = "-"; - ostr << endl - << _FB_CONSOLETEXT(Common, CompiledOptions, "Compiled options", "Options used when compiled") - << " (" << NOT << " => " - << _FB_CONSOLETEXT(Common, Disabled, "disabled", "option is turned off") << "): " << endl - << - -/**** NOTE: This list is in alphabetical order! ****/ - -#ifndef HAVE_FRIBIDI - NOT << -#endif - "BIDI" << endl << - -#ifndef DEBUG - NOT << -#endif // DEBUG - "DEBUG" << endl << - -#ifndef USE_EWMH - NOT << -#endif // USE_EWMH - "EWMH" << endl << - -#ifndef HAVE_IMLIB2 - NOT<< -#endif // HAVE_IMLIB2 - "IMLIB2" << endl << - -#ifndef NLS - NOT<< -#endif // NLS - "NLS" << endl << - -#ifndef REMEMBER - NOT << -#endif // REMEMBER - "REMEMBER" << endl << - -#ifndef HAVE_XRENDER - NOT << -#endif // HAVE_XRENDER - "RENDER" << endl << - -#ifndef SHAPE - NOT << -#endif // SHAPE - "SHAPE" << endl << - -#ifndef USE_SLIT - NOT << -#endif // SLIT - "SLIT" << endl << - -#ifndef USE_SYSTRAY - NOT << -#endif - "SYSTEMTRAY" << endl << - - -#ifndef USE_TOOLBAR - NOT << -#endif // USE_TOOLBAR - "TOOLBAR" << endl << - -#ifndef HAVE_RANDR - NOT << -#endif - "RANDR" << -#ifdef HAVE_RANDR1_2 - "1.2" << -#endif - endl << - -#ifndef USE_XFT - NOT << -#endif // USE_XFT - "XFT" << endl << - -#ifndef XINERAMA - NOT << -#endif // XINERAMA - "XINERAMA" << endl << - -#ifndef USE_XMB - NOT << -#endif // USE_XMB - "XMB" << endl << - -#ifndef HAVE_XPM - NOT << -#endif // HAVE_XPM - "XPM" << endl - - << endl; -} - -struct Options { - Options() : xsync(false) { - - const char* env; - - env = getenv("DISPLAY"); - if (env && strlen(env) > 0) { - session_display.assign(env); - } - - rc_path = FbTk::StringUtil::expandFilename(std::string("~/.") + realProgramName("fluxbox")); - - if (!rc_path.empty()) { - rc_file = rc_path + "/init"; - } - } - - - std::string session_display; - std::string rc_path; - std::string rc_file; - std::string log_filename; - bool xsync; -}; - -static void parseOptions(int argc, char** argv, Options& opts) { +void handleSignal(int signum) { _FB_USES_NLS; + static int re_enter = 0; - int i; - for (i = 1; i < argc; ++i) { - string arg(argv[i]); - if (arg == "-rc" || arg == "--rc") { - // look for alternative rc file to use - - if ((++i) >= argc) { - cerr<<_FB_CONSOLETEXT(main, RCRequiresArg, - "error: '-rc' requires an argument", "the -rc option requires a file argument")<= argc) { - cerr<<_FB_CONSOLETEXT(main, DISPLAYRequiresArg, - "error: '-display' requires an argument", - "")<= argc) { - cerr<<_FB_CONSOLETEXT(main, LOGRequiresArg, "error: '-log' needs an argument", "")<\t\tuse display connection.\n" - "-screen \trun on specified screens only.\n" - "-rc \t\t\tuse alternate resource file.\n" - "-version\t\t\tdisplay version and exit.\n" - "-info\t\t\t\tdisplay some useful information.\n" - "-list-commands\t\t\tlist all valid key commands.\n" - "-sync\t\t\t\tsynchronize with X server for debugging.\n" - "-log \t\t\tlog output to file.\n" - "-help\t\t\t\tdisplay this help text and exit.\n\n", - - "Main usage string. Please lay it out nicely. There is one %s that is given the version").c_str(), - __fluxbox_version, "2001-2013"); - exit(EXIT_SUCCESS); - } else if (arg == "-info" || arg == "-i" || arg == "--info") { - showInfo(cout); - exit(EXIT_SUCCESS); - } else if (arg == "-list-commands" || arg == "--list-commands") { - FbTk::CommandParser::CreatorMap cmap = FbTk::CommandParser::instance().creatorMap(); - FbTk::CommandParser::CreatorMap::const_iterator it = cmap.begin(); - const FbTk::CommandParser::CreatorMap::const_iterator it_end = cmap.end(); - for (; it != it_end; ++it) - cout << it->first << endl; - exit(EXIT_SUCCESS); - } else if (arg == "-verbose" || arg == "--verbose") { - FbTk::ThemeManager::instance().setVerbose(true); - } - } -} - -#ifdef _WIN32 -/** - Wrapper function for Windows builds - mkdir takes only one param. -*/ -static int mkdir(const char *dirname, int /*permissions*/) { - return mkdir(dirname); -} + switch (signum) { +#ifndef _WIN32 + case SIGCHLD: // we don't want the child process to kill us + // more than one process may have terminated + while (waitpid(-1, 0, WNOHANG | WUNTRACED) > 0); + break; + case SIGHUP: + // xinit sends HUP when it wants to go down. there is no point in + // restoring anything in the screens / workspaces, the connection + // to the xserver might drop any moment + if (fluxbox.get()) { fluxbox->shutdown(1); } + break; + case SIGUSR1: + if (fluxbox.get()) { fluxbox->restart(); } + break; + case SIGUSR2: + if (fluxbox.get()) { fluxbox->reconfigure(); } + break; #endif - -/** - setup the configutation files in - home directory -*/ -void setupConfigFiles(const std::string& dirname, const std::string& rc) { - - _FB_USES_NLS; - - const bool has_dir = FbTk::FileUtil::isDirectory(dirname.c_str()); - - - struct CFInfo { - bool create_file; - const char* default_name; - const std::string filename; - } cfiles[] = { - { !has_dir, DEFAULT_INITFILE, rc }, - { !has_dir, DEFAULTKEYSFILE, dirname + "/keys" }, - { !has_dir, DEFAULTMENU, dirname + "/menu" }, - { !has_dir, DEFAULT_APPSFILE, dirname + "/apps" }, - { !has_dir, DEFAULT_OVERLAY, dirname + "/overlay" }, - { !has_dir, DEFAULT_WINDOWMENU, dirname + "/windowmenu" } - }; - const size_t nr_of_cfiles = sizeof(cfiles)/sizeof(CFInfo); - - - if (has_dir) { // check if anything with these names exists, if not create new - for (size_t i = 0; i < nr_of_cfiles; ++i) { - cfiles[i].create_file = access(cfiles[i].filename.c_str(), F_OK); + case SIGSEGV: + abort(); + break; + case SIGALRM: + // last resort for shutting down fluxbox. the alarm() is set in + // Fluxbox::shutdown() + if (fluxbox.get() && fluxbox->isShuttingDown()) { + cerr << "fluxbox took longer than expected to shutdown\n"; + exit(13); } - } else { + break; + case SIGFPE: + case SIGINT: +#ifndef _WIN32 + case SIGPIPE: +#endif + case SIGTERM: + if (fluxbox.get()) { fluxbox->shutdown(); } + break; + default: + fprintf(stderr, + _FB_CONSOLETEXT(BaseDisplay, SignalCaught, + "%s: signal %d caught\n", + "signal catch debug message. Include %s for Command and %d for signal number").c_str(), + "TODO: m_arg[0]", signum); - fbdbg << "Creating dir: " << dirname << endl; - if (mkdir(dirname.c_str(), 0700)) { - fprintf(stderr, _FB_CONSOLETEXT(Fluxbox, ErrorCreatingDirectory, - "Can't create %s directory", - "Can't create a directory, one %s for directory name").c_str(), - dirname.c_str()); - cerr << endl; - return; + if (! fluxbox->isStartup() && ! re_enter) { + re_enter = 1; + cerr<<_FB_CONSOLETEXT(BaseDisplay, ShuttingDown, + "Shutting Down\n", + "Quitting because of signal, end with newline"); + if (fluxbox.get()) { fluxbox->shutdown(); } } - } - bool sync_fs = false; + cerr << _FB_CONSOLETEXT(BaseDisplay, Aborting, + "Aborting... dumping core\n", + "Aboring and dumping core, end with newline"); + abort(); + break; + } +} - // copy default files if needed - for (size_t i = 0; i < nr_of_cfiles; ++i) { - if (cfiles[i].create_file) { - FbTk::FileUtil::copyFile(FbTk::StringUtil::expandFilename(cfiles[i].default_name).c_str(), cfiles[i].filename.c_str()); - sync_fs = true; - } - } -#ifdef HAVE_SYNC - if (sync_fs) { - sync(); - } +void setupSignalHandling() { + signal(SIGSEGV, handleSignal); + signal(SIGSEGV, handleSignal); + signal(SIGFPE, handleSignal); + signal(SIGTERM, handleSignal); + signal(SIGINT, handleSignal); +#ifdef HAVE_ALARM + signal(SIGALRM, handleSignal); +#endif +#ifndef _WIN32 + signal(SIGPIPE, handleSignal); // e.g. output sent to grep + signal(SIGCHLD, handleSignal); + signal(SIGHUP, handleSignal); + signal(SIGUSR1, handleSignal); + signal(SIGUSR2, handleSignal); #endif } - -// configs might be out of date, so run fluxbox-update_configs -// if necassary. -void updateConfigFilesIfNeeded(const std::string& rc_file) { - - const int CONFIG_VERSION = 13; // TODO: move this to 'defaults.hh' or 'config.h' - - FbTk::ResourceManager r_mgr(rc_file.c_str(), false); - FbTk::Resource c_version(r_mgr, 0, "session.configVersion", "Session.ConfigVersion"); - - if (!r_mgr.load(rc_file.c_str())) { - _FB_USES_NLS; - cerr << _FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "") - << ": " - << rc_file << endl; - return; - } - - if (*c_version < CONFIG_VERSION) { - - fbdbg << "updating config files from version " - << *c_version - << " to " - << CONFIG_VERSION - << endl; - - string commandargs = realProgramName("fluxbox-update_configs"); - commandargs += " -rc " + rc_file; - - if (system(commandargs.c_str())) { - fbdbg << "running '" - << commandargs - << "' failed." << endl; - } -#ifdef HAVE_SYNC - sync(); -#endif // HAVE_SYNC - } } - int main(int argc, char **argv) { FbTk::NLSInit("fluxbox.cat"); - Options opts; - parseOptions(argc, argv, opts); + FluxboxCli::Options opts; + int exitcode = opts.parse(argc, argv); + + if (exitcode != -1) { + exit(exitcode); + } + exitcode = EXIT_FAILURE; #ifdef __EMX__ _chdir2(getenv("X11ROOT")); @@ -474,19 +188,16 @@ int main(int argc, char **argv) { << ": " << opts.log_filename < fluxbox; try { fluxbox.reset(new Fluxbox(argc, argv, @@ -494,8 +205,8 @@ int main(int argc, char **argv) { opts.rc_path, opts.rc_file, opts.xsync)); + setupSignalHandling(); fluxbox->eventLoop(); - exitcode = EXIT_SUCCESS; } catch (out_of_range &oor) { diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 6b3809d3..b6678ce8 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -3,7 +3,6 @@ AM_CPPFLAGS= -I$(top_srcdir)/src noinst_PROGRAMS= \ testTexture \ testFont \ - testSignals \ testKeys \ testDemandAttention \ testFullscreen \ @@ -12,7 +11,6 @@ noinst_PROGRAMS= \ testTexture_SOURCES = texturetest.cc testFont_SOURCES = testFont.cc -testSignals_SOURCES = testSignals.cc testKeys_SOURCES = testKeys.cc testDemandAttention_SOURCES = testDemandAttention.cc #testResource_SOURCES = Resourcetest.cc diff --git a/src/tests/signaltest.cc b/src/tests/signaltest.cc deleted file mode 100644 index 09ebdacf..00000000 --- a/src/tests/signaltest.cc +++ /dev/null @@ -1,86 +0,0 @@ -// signaltest.cc for testing signal handler in fluxbox -// Copyright (c) 2002 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#include "../FbTk/SignalHandler.hh" - -#include -#ifdef HAVE_CASSERT - #include -#else - #include -#endif - -using namespace std; -using namespace FbTk; - -class IntSig:public SignalEventHandler { -public: - void handleSignal(int signum) { - assert(signum == SIGINT); - cerr<<"Signal SIGINT!"< -using namespace std; - -#include "../FbTk/Signal.hh" -#include "../FbTk/MemFun.hh" - -#include - - - -struct NoArgument { - void operator() () const { - cout << "No Argument." << endl; - } -}; - -struct OneArgument { - void operator ()( int value ) { - cout << "One argument = " << value << endl; - } -}; - -struct TwoArguments { - template - void operator ()( const T1& value, const T2& message ) { - cout << "Two arguments, (1) = " << value << ", (2) = " << message << endl; - } -}; - -struct ThreeArguments { - void operator ()( int value, const string& message, double value2 ) { - cout << "Two arguments, (1) = " << value << ", (2) = " << message - << ", (3) = " << value2 << endl; - } -}; - -struct FunctionClass { - FunctionClass() { - cout << "FunctionClass created." << endl; - } - ~FunctionClass() { - cout << "FunctionClass deleted." << endl; - } - void print() { - cout << "Printing." << endl; - } - - void takeIt( string& str ) { - cout << "FunctionClass::takeIt( " << str << " )" << endl; - } - - void showMessage( int value, const string& message ) { - cout << "(" << value << "): " << message << endl; - } - void showMessage2( const string& message1, const string& message2) { - cout << "(" << message1 << ", " << message2 << ")" << endl; - } - void threeArgs( int value, const string& str, double pi ) { - cout << "(" << value << "): " << str << ", pi = " << pi << endl; - } - -}; - -struct Printer { - void printInt(int value) { - cout << "Int:" << value << endl; - } - void printString(string value) { - cout << "string:" << value << endl; - } - void printFloat(float value) { - cout << "Float:" << value << endl; - } -}; - -int main() { - using FbTk::Signal; - using FbTk::SignalTracker; - - Signal<> no_arg; - no_arg.connect( NoArgument() ); - - Signal one_arg; - one_arg.connect( OneArgument() ); - - Signal two_args; - two_args.connect( TwoArguments() ); - - Signal three_args; - three_args.connect( ThreeArguments() ); - - // emit test - no_arg.emit(); - one_arg.emit( 10 ); - two_args.emit( 10, "Message" ); - three_args.emit( 10, "Three", 3.141592 ); - - // test signal tracker - { - cout << "---- tracker ----" << endl; - SignalTracker tracker; - // setup two new slots and track them - SignalTracker::TrackID id_no_arg = tracker.join( no_arg, NoArgument() ); - SignalTracker::TrackID id_one_arg = tracker.join( one_arg, OneArgument() ); - - // two outputs each from these two signals - no_arg.emit(); - one_arg.emit( 31 ); - - // stop tracking id_one_arg, which should keep the slot after this scope, - // the id_no_arg connection should be destroyed after this. - tracker.leave( id_one_arg ); - cout << "---- tracker end ----" << endl; - } - - // now we should have one output from no_arg and two outputs from one_arg - no_arg.emit(); - one_arg.emit( 2 ); - - using FbTk::MemFun; - FunctionClass obj; - no_arg.clear(); - no_arg.connect(MemFun(obj, &FunctionClass::print)); - no_arg.emit(); - - string takeThis("Take this"); - Signal ref_arg; - ref_arg.connect(MemFun(obj, &FunctionClass::takeIt)); - ref_arg.emit( takeThis ); - - two_args.clear(); - two_args.connect(MemFun(obj, &FunctionClass::showMessage)); - two_args.emit(10, "This is a message"); - - three_args.clear(); - three_args.connect(MemFun(obj, &FunctionClass::threeArgs)); - three_args.emit(9, "nine", 3.141592); - - // Test ignore signals - { - cout << "----------- Testing ignoring arguments for signal." << endl; - using FbTk::MemFunIgnoreArgs; - // Create a signal that emits with three arguments, and connect - // sinks that takes less than three arguments. - Signal more_args; - more_args.connect(MemFunIgnoreArgs(obj, &FunctionClass::print)); - more_args.connect(MemFunIgnoreArgs(obj, &FunctionClass::takeIt)); - more_args.connect(MemFunIgnoreArgs(obj, &FunctionClass::showMessage2)); - more_args.emit("This should be visible for takeIt(string)", - "Visible to the two args function.", - 2.9); - - } - - // Test argument selector - { - using namespace FbTk; - Signal source; - - Printer printer; - source.connect(MemFunSelectArg0(printer, &Printer::printInt)); - source.connect(MemFunSelectArg1(printer, &Printer::printString)); - source.connect(MemFunSelectArg2(printer, &Printer::printFloat)); - - source.emit(10, "hello", 3.141592); - - Signal source2; - source2.connect(MemFunSelectArg0(printer, &Printer::printString)); - source2.connect(MemFunSelectArg1(printer, &Printer::printInt)); - source2.emit("world", 37); - } -}