~nickbp/gridmgr

153a7b706c278b7064e2fab3a8966671f625ee1b — Nick Parker 9 years ago 2823c92
Streamline logging interface

Previously, separate macros were needed for cases where there were no
printf-style separated formatting/value arguments, eg 'LOG("hello");'.

This updates things such that the same LOG macro handles both cases,
and removes many other permutations which weren't being used anyway.
M src/config.cpp => src/config.cpp +41 -3
@@ 24,29 24,67 @@ namespace config {
    FILE *fout = stdout, *ferr = stderr;
    bool debug_enabled = false;

    void _debug(const char* format, ...) {
    void _debug(const char* func, const char* format, ...) {
        if (debug_enabled) {
            va_list args;
            va_start(args, format);
            if (func != NULL) {
                fprintf(fout, "DEBUG %s ", func);
            }
            vfprintf(fout, format, args);
            va_end(args);
            fprintf(fout, "\n");
        }
    }
    void _debug(const char* func, ...) {
        if (debug_enabled) {
            va_list args;
            va_start(args, func);
            if (func != NULL) {
                fprintf(fout, "DEBUG %s ", func);
            }
            vfprintf(fout, "%s\n", args);//only one arg, the string itself
            va_end(args);
        }
    }

    void _log(const char* format, ...) {
    void _log(const char* func, const char* format, ...) {
        va_list args;
        va_start(args, format);
        if (func != NULL) {
            fprintf(fout, "LOG %s() ", func);
        }
        vfprintf(fout, format, args);
        va_end(args);
        fprintf(fout, "\n");
    }
    void _log(const char* func, ...) {
        va_list args;
        va_start(args, func);
        if (func != NULL) {
            fprintf(fout, "LOG %s() ", func);
        }
        vfprintf(fout, "%s\n", args);//only one arg, the string itself
        va_end(args);
    }

    void _error(const char* format, ...) {
    void _error(const char* func, const char* format, ...) {
        va_list args;
        va_start(args, format);
        if (func != NULL) {
            fprintf(ferr, "ERROR %s() ", func);
        }
        vfprintf(ferr, format, args);
        va_end(args);
        fprintf(ferr, "\n");
    }
    void _error(const char* func, ...) {
        va_list args;
        va_start(args, func);
        if (func != NULL) {
            fprintf(ferr, "ERROR %s() ", func);
        }
        vfprintf(ferr, "%s\n", args);//only one arg, the string itself
        va_end(args);
    }
}

M src/config.in.h => src/config.in.h +15 -26
@@ 21,30 21,14 @@

#include <stdio.h>

#define _PRINT_PREFIX "%s %s  "
#define _PRINT_ARGS __FUNCTION__

/* Some simple print helpers */

/* Format str and file/line prefix */
#define DEBUG(format, ...) config::_debug(_PRINT_PREFIX format, "DEBUG", _PRINT_ARGS, __VA_ARGS__)
#define LOG(format, ...) config::_log(_PRINT_PREFIX format, "LOG", _PRINT_ARGS, __VA_ARGS__)
#define ERROR(format, ...) config::_error(_PRINT_PREFIX format, "ERR", _PRINT_ARGS, __VA_ARGS__)

/* No file/line prefix ("RAW") */
#define DEBUG_RAW(format, ...) config::_debug(format, __VA_ARGS__)
#define LOG_RAW(format, ...) config::_log(format, __VA_ARGS__)
#define ERROR_RAW(format, ...) config::_error(format, __VA_ARGS__)

/* No format str ("Direct" -> "DIR") */
#define DEBUG_DIR(...) config::_debug(_PRINT_PREFIX "%s", "DEBUG", _PRINT_ARGS, __VA_ARGS__)
#define LOG_DIR(...) config::_log(_PRINT_PREFIX "%s", "LOG", _PRINT_ARGS, __VA_ARGS__)
#define ERROR_DIR(...) config::_error(_PRINT_PREFIX "%s", "ERR", _PRINT_ARGS, __VA_ARGS__)
#define DEBUG(...) config::_debug(__FUNCTION__, __VA_ARGS__)
#define LOG(...) config::_log(__FUNCTION__, __VA_ARGS__)
#define ERROR(...) config::_error(__FUNCTION__, __VA_ARGS__)

/* No format str and no file/line prefix */
#define DEBUG_RAWDIR(...) config::_debug(__VA_ARGS__)
#define LOG_RAWDIR(...) config::_log(__VA_ARGS__)
#define ERROR_RAWDIR(...) config::_error(__VA_ARGS__)
/* Skips "ERR" and func name in output. Used by help output. */
#define PRINT_HELP(...) config::_error(NULL, __VA_ARGS__)

#cmakedefine USE_XINERAMA



@@ 57,16 41,21 @@ namespace config {
    static const char VERSION_STRING[] = "@gridmgr_VERSION_MAJOR@.@gridmgr_VERSION_MINOR@.@gridmgr_VERSION_PATCH@";
    static const char BUILD_DATE[] = __TIMESTAMP__;

    /* DONT USE THESE, use DEBUG()/LOG()/ERROR() instead: */

    extern FILE *fout;
    extern FILE *ferr;

    extern bool debug_enabled;
    void _debug(const char* format, ...);

    void _log(const char* format, ...);
    void _error(const char* format, ...);
    /* DONT USE THESE DIRECTLY, use DEBUG()/LOG()/ERROR() instead.
     * The ones with a 'format' function support printf-style format before a list of args.
     * The ones without are for direct unformatted output (eg "_error("func", "printme");") */
    void _debug(const char* func, const char* format, ...);
    void _debug(const char* func, ...);

    void _log(const char* func, const char* format, ...);
    void _log(const char* func, ...);
    void _error(const char* func, const char* format, ...);
    void _error(const char* func, ...);
}

#endif

M src/main.cpp => src/main.cpp +44 -44
@@ 28,58 28,58 @@
#define TIMESTR_MAX 128 // arbitrarily large

static void syntax(char* appname) {
    ERROR_RAWDIR("");
    ERROR_RAWDIR("gridmgr v%s (built %s)",
    PRINT_HELP("");
    PRINT_HELP("gridmgr v%s (built %s)",
          config::VERSION_STRING,
          config::BUILD_DATE);
    ERROR_RAWDIR("");
    ERROR_RAWDIR("Performs one or more of the following, in this order:");
    ERROR_RAWDIR("- Activate a window adjacent to the current window.");
    PRINT_HELP("");
    PRINT_HELP("Performs one or more of the following, in this order:");
    PRINT_HELP("- Activate a window adjacent to the current window.");
#ifdef USE_XINERAMA
    ERROR_RAWDIR("- Move active window to an adjacent monitor.");
    PRINT_HELP("- Move active window to an adjacent monitor.");
#endif
    ERROR_RAWDIR("- Position active window on a grid layout.");
    ERROR_RAWDIR("");
    PRINT_HELP("- Position active window on a grid layout.");
    PRINT_HELP("");
#ifdef USE_XINERAMA
    ERROR_RAWDIR("Usage: %s [options] <window/monitor/position> [w/m/p] [w/m/p]", appname);
    PRINT_HELP("Usage: %s [options] <window/monitor/position> [w/m/p] [w/m/p]", appname);
#else
    ERROR_RAWDIR("Usage: %s [options] <window/position> [w/p] [w/p]", appname);
    PRINT_HELP("Usage: %s [options] <window/position> [w/p] [w/p]", appname);
#endif
    ERROR_RAWDIR("");
    ERROR_RAWDIR("Windows (activate adjacent (w)indow):");
    ERROR_RAWDIR("  -------- --------- ---------  ");
    ERROR_RAWDIR(" | wuleft |   wup   | wuright | ");
    ERROR_RAWDIR(" |------- + ------- + --------| ");
    ERROR_RAWDIR(" | wleft  |         |  wright | ");
    ERROR_RAWDIR(" |------- + ------- + --------| ");
    ERROR_RAWDIR(" | wdleft |  wdown  | wdright | ");
    ERROR_RAWDIR("  -------- --------- ---------  ");
    PRINT_HELP("");
    PRINT_HELP("Windows (activate adjacent (w)indow):");
    PRINT_HELP("  -------- --------- ---------  ");
    PRINT_HELP(" | wuleft |   wup   | wuright | ");
    PRINT_HELP(" |------- + ------- + --------| ");
    PRINT_HELP(" | wleft  |         |  wright | ");
    PRINT_HELP(" |------- + ------- + --------| ");
    PRINT_HELP(" | wdleft |  wdown  | wdright | ");
    PRINT_HELP("  -------- --------- ---------  ");
#ifdef USE_XINERAMA
    ERROR_RAWDIR("");
    ERROR_RAWDIR("Monitors (move window to adjacent (m)onitor):");
    ERROR_RAWDIR("  -------- --------- ---------  ");
    ERROR_RAWDIR(" | muleft |   mup   | muright | ");
    ERROR_RAWDIR(" |------- + ------- + --------| ");
    ERROR_RAWDIR(" | mleft  |         |  mright | ");
    ERROR_RAWDIR(" |------- + ------- + --------| ");
    ERROR_RAWDIR(" | mdleft |  mdown  | mdright | ");
    ERROR_RAWDIR("  -------- --------- ---------  ");
    PRINT_HELP("");
    PRINT_HELP("Monitors (move window to adjacent (m)onitor):");
    PRINT_HELP("  -------- --------- ---------  ");
    PRINT_HELP(" | muleft |   mup   | muright | ");
    PRINT_HELP(" |------- + ------- + --------| ");
    PRINT_HELP(" | mleft  |         |  mright | ");
    PRINT_HELP(" |------- + ------- + --------| ");
    PRINT_HELP(" | mdleft |  mdown  | mdright | ");
    PRINT_HELP("  -------- --------- ---------  ");
#endif
    ERROR_RAWDIR("");
    ERROR_RAWDIR("Positions (position window on (g)rid):");
    ERROR_RAWDIR("  -------- --------- ---------  ");
    ERROR_RAWDIR(" | guleft |   gup   | guright | ");
    ERROR_RAWDIR(" |------- + ------- + --------| ");
    ERROR_RAWDIR(" | gleft  | gcenter |  gright | ");
    ERROR_RAWDIR(" |------- + ------- + --------| ");
    ERROR_RAWDIR(" | gdleft |  gdown  | gdright | ");
    ERROR_RAWDIR("  -------- --------- ---------  ");
    ERROR_RAWDIR("");
    ERROR_RAWDIR("Options:");
    ERROR_RAWDIR("  -h/--help        This help text.");
    ERROR_RAWDIR("  -v/--verbose     Show verbose output.");
    ERROR_RAWDIR("  --log <file>     Append any output to <file>.");
    ERROR_RAWDIR("");
    PRINT_HELP("");
    PRINT_HELP("Positions (position window on (g)rid):");
    PRINT_HELP("  -------- --------- ---------  ");
    PRINT_HELP(" | guleft |   gup   | guright | ");
    PRINT_HELP(" |------- + ------- + --------| ");
    PRINT_HELP(" | gleft  | gcenter |  gright | ");
    PRINT_HELP(" |------- + ------- + --------| ");
    PRINT_HELP(" | gdleft |  gdown  | gdright | ");
    PRINT_HELP("  -------- --------- ---------  ");
    PRINT_HELP("");
    PRINT_HELP("Options:");
    PRINT_HELP("  -h/--help        This help text.");
    PRINT_HELP("  -v/--verbose     Show verbose output.");
    PRINT_HELP("  --log <file>     Append any output to <file>.");
    PRINT_HELP("");
}

static bool strsub_to_pos(const char* arg, grid::POS& out, bool center_is_valid) {


@@ 197,7 197,7 @@ static bool parse_config(int argc, char* argv[]) {
                    struct tm now_tm;
                    localtime_r(&now, &now_tm);
                    if (strftime(now_s, TIMESTR_MAX, "%a, %d %b %Y %T %z", &now_tm) == 0) {
                        ERROR_DIR("strftime failed");
                        ERROR("strftime failed");
                        return false;
                    }
                }

M src/viewport-imp-ewmh.cpp => src/viewport-imp-ewmh.cpp +3 -3
@@ 29,7 29,7 @@ bool viewport::ewmh::get_viewports(Display* disp, const Dimensions& /*activewin*
        static Atom curdesk_msg = XInternAtom(disp, "_NET_CURRENT_DESKTOP", False);
        if (!(cur_ptr = (unsigned long *)x11_util::get_property(disp, DefaultRootWindow(disp),
                                XA_CARDINAL, curdesk_msg, NULL))) {
            ERROR_DIR("unable to retrieve current desktop");
            ERROR("unable to retrieve current desktop");
            return false;
        }
        cur_workspace = *cur_ptr;


@@ 41,11 41,11 @@ bool viewport::ewmh::get_viewports(Display* disp, const Dimensions& /*activewin*
    static Atom workarea_msg = XInternAtom(disp, "_NET_WORKAREA", False);
    if (!(area = (unsigned long*)x11_util::get_property(disp, DefaultRootWindow(disp),
                            XA_CARDINAL, workarea_msg, &area_count))) {
        ERROR_DIR("unable to retrieve spanning workarea");
        ERROR("unable to retrieve spanning workarea");
        return false;
    }
    if (area_count == 0) {
        ERROR_DIR("unable to retrieve spanning workarea.");
        ERROR("unable to retrieve spanning workarea.");
        x11_util::free_property(area);
        return false;
    }

M src/viewport-imp-xinerama.cpp => src/viewport-imp-xinerama.cpp +3 -3
@@ 41,7 41,7 @@ namespace {
        int screen_count = 0;
        XineramaScreenInfo* screens = XineramaQueryScreens(disp, &screen_count);
        if (screens == NULL || screen_count == 0) {
            DEBUG_DIR("xinerama not loaded or unavailable");
            DEBUG("xinerama not loaded or unavailable");
            if (screens != NULL) {
                XFree(screens);
            }


@@ 124,7 124,7 @@ namespace {
        static Atom clientlist_msg = XInternAtom(disp, "_NET_CLIENT_LIST", False);
        if (!(clients = (Window*)x11_util::get_property(disp, DefaultRootWindow(disp),
                                XA_WINDOW, clientlist_msg, &client_count))) {
            ERROR_DIR("unable to retrieve list of clients");
            ERROR("unable to retrieve list of clients");
            return false;
        }
        for (size_t i = 0; i < client_count; ++i) {


@@ 137,7 137,7 @@ namespace {
                continue;
            }
            if (xstrut_count != 12) {//nice to have
                ERROR_DIR("incorrect number of strut values: got %lu, expected 12", xstrut_count);
                ERROR("incorrect number of strut values: got %lu, expected 12", xstrut_count);
                x11_util::free_property(clients);
                x11_util::free_property(xstrut);
                return false;

M src/viewport.cpp => src/viewport.cpp +1 -1
@@ 32,7 32,7 @@ namespace {
            dim_list_t& viewports, size_t& active) {
        Display* disp = XOpenDisplay(NULL);
        if (disp == NULL) {
            ERROR_DIR("unable to get display");
            ERROR("unable to get display");
            return false;
        }


M src/window.cpp => src/window.cpp +19 -19
@@ 61,7 61,7 @@ namespace {
        unsigned int width, height, border, depth;
        if (XGetGeometry(disp, win, &root, &x, &y, &width,
                        &height, &border, &depth) == 0) {
            ERROR_DIR("get geometry failed");
            ERROR("get geometry failed");
            return;
        }
        DEBUG("  %dx %dy %uw %uh %ub", x, y, width, height, border);


@@ 72,7 72,7 @@ namespace {
        Window* ret = (Window*)x11_util::get_property(disp, DefaultRootWindow(disp),
                XA_WINDOW, actwin_msg, NULL);
        if (ret == NULL) {
            ERROR_DIR("unable to get active window");
            ERROR("unable to get active window");
        }
        return ret;
    }


@@ 85,7 85,7 @@ namespace {
        static Atom wintype_msg = XInternAtom(disp, "_NET_WM_WINDOW_TYPE", False);
        Atom* types = (Atom*)x11_util::get_property(disp, win, XA_ATOM, wintype_msg, &count);
        if (types == NULL) {
            ERROR_DIR("couldn't get window types");
            ERROR("couldn't get window types");
            //assume window types are fine, keep going
        } else {
            static Atom desktop_type = XInternAtom(disp, "_NET_WM_WINDOW_TYPE_DESKTOP", False),


@@ 113,7 113,7 @@ namespace {
        static Atom state_msg = XInternAtom(disp, "_NET_WM_STATE", False);
        Atom* states = (Atom*)x11_util::get_property(disp, win, XA_ATOM, state_msg, &count);
        if (states == NULL) {
            ERROR_DIR("couldn't get window states");
            ERROR("couldn't get window states");
            //assume window states are fine, keep going
        } else {
            static Atom skip_pager = XInternAtom(disp, "_NET_WM_STATE_SKIP_PAGER", False),


@@ 146,13 146,13 @@ namespace {
            unsigned int border, depth;
            if (XGetGeometry(disp, win, &root, &x, &y, &internal_width,
                            &internal_height, &border, &depth) == 0) {
                ERROR_DIR("get geometry failed");
                ERROR("get geometry failed");
                return false;
            }
        }

        if (win == root) {
            ERROR_DIR("this window is root! treating this as an error.");
            ERROR("this window is root! treating this as an error.");
            return false;
        }



@@ 168,7 168,7 @@ namespace {
                just_before_root = parent;
                if (XQueryTree(disp, just_before_root, &root,
                                &parent, &children, &children_count) == 0) {
                    ERROR_DIR("get query tree failed");
                    ERROR("get query tree failed");
                    return false;
                }
                if (children != NULL) {


@@ 186,7 186,7 @@ namespace {
            unsigned int border, depth;
            if (XGetGeometry(disp, just_before_root, &root, &x, &y, &external_width,
                            &external_height, &border, &depth) == 0) {
                ERROR_DIR("get geometry failed");
                ERROR("get geometry failed");
                return false;
            }
        }


@@ 217,7 217,7 @@ namespace {
        static Atom active_msg = XInternAtom(disp, "_NET_ACTIVE_WINDOW", False);
        if (!_client_msg(disp, newactive, active_msg,
                        SOURCE_INDICATION, CurrentTime, curactive, 0, 0)) {
            ERROR_DIR("couldn't activate");
            ERROR("couldn't activate");
            return false;
        }
        return true;


@@ 246,7 246,7 @@ namespace {
bool window::select_activate(grid::POS dir) {
    Display* disp = XOpenDisplay(NULL);
    if (disp == NULL) {
        ERROR_DIR("unable to get display");
        ERROR("unable to get display");
        return false;
    }



@@ 258,7 258,7 @@ bool window::select_activate(grid::POS dir) {
        Window* all_wins = (Window*)x11_util::get_property(disp, DefaultRootWindow(disp),
                XA_WINDOW, clientlist_msg, &win_count);
        if (all_wins == NULL || win_count == 0) {
            ERROR_DIR("unable to get list of windows");
            ERROR("unable to get list of windows");
            if (all_wins != NULL) {
                x11_util::free_property(all_wins);
            }


@@ 285,7 285,7 @@ bool window::select_activate(grid::POS dir) {
        for (size_t i = 0; i < wins.size(); ++i) {
            if (wins[i] == *active) {
                active_window = i;
                DEBUG_DIR("ACTIVE:");
                DEBUG("ACTIVE:");
            }
            all_windows.push_back(Dimensions());
            get_window_size(disp, wins[i], &all_windows.back(), NULL, NULL);


@@ 315,7 315,7 @@ bool ActiveWindow::init() {
    if (disp == NULL) {
        disp = XOpenDisplay(NULL);
        if (disp == NULL) {
            ERROR_DIR("unable to get display");
            ERROR("unable to get display");
            return false;
        }
    }


@@ 335,12 335,12 @@ bool ActiveWindow::Size(Dimensions& activewin) {
    }

    if (is_dock_window(disp, *win) || is_menu_window(disp, *win)) {
        LOG_DIR("Active window is a desktop or dock. Ignoring move request.");
        LOG("Active window is a desktop or dock. Ignoring move request.");
        return false;
    }

    if (!get_window_size(disp, *win, &activewin, NULL, NULL)) {
        ERROR_DIR("couldn't get window size");
        ERROR("couldn't get window size");
        return false;
    }



@@ 362,7 362,7 @@ bool ActiveWindow::MoveResize(const Dimensions& activewin) {

    //demaximize the window before attempting to move it
    if (!maximize_window(disp, *win, false)) {
        ERROR_DIR("couldn't demaximize");
        ERROR("couldn't demaximize");
        //disregard failure
    }



@@ 390,7 390,7 @@ bool ActiveWindow::Maximize() {
    }

    if (!maximize_window(disp, *win, true)) {
        ERROR_DIR("couldn't maximize");
        ERROR("couldn't maximize");
        return false;
    }
    return true;


@@ 402,7 402,7 @@ bool ActiveWindow::DeFullscreen() {

    static Atom fs = XInternAtom(disp, "_NET_WM_STATE_FULLSCREEN", False);
    if (!set_window_state(disp, *win, fs, 0, false)) {
        ERROR_DIR("couldn't defullscreen");
        ERROR("couldn't defullscreen");
        return false;
    }
    return true;


@@ 414,7 414,7 @@ bool ActiveWindow::DeShade() {

    static Atom shade = XInternAtom(disp, "_NET_WM_STATE_SHADED", False);
    if (!set_window_state(disp, *win, shade, 0, false)) {
        ERROR_DIR("couldn't deshade");
        ERROR("couldn't deshade");
        return false;
    }
    return true;